linq group by with c# - c#

I have made a method in my Models class to call set of data from data base by below codes:
public IQueryable result(string username, string exam)
{
return (from result in idb.User_Exam_Question
where (result.User_Tbl_email == username && result.Exam_Tbl_ID == Convert.ToInt32(exam))
group result by result.category_tbl_ID into cat
select cat);
}
but I need to count the rows of each category . how should I change the above code to get my desirable output .
many thanks

If you want to return the count, just add .Count():
public int result(string username, string exam)
{
return (from result in idb.User_Exam_Question
where (result.User_Tbl_email == username && result.Exam_Tbl_ID == Convert.ToInt32(exam))
group result by result.category_tbl_ID into cat
select cat).Count();
}
Or, if you want each sub-result as a count, you can do this:
public IQueryable result(string username, string exam)
{
return from result in idb.User_Exam_Question
where (result.User_Tbl_email == username && result.Exam_Tbl_ID == Convert.ToInt32(exam))
group result by result.category_tbl_ID into cat
select new
{
CatCount = cat.Count()
}
}
You can then do something like this:
result("username", "exam")[0].CatCount;
// returns the count of the first result of the query.

You can get the count directly from your cat !
public IQueryable result(string username, string exam)
{
return (from result in idb.User_Exam_Question
where (result.User_Tbl_email == username && result.Exam_Tbl_ID == Convert.ToInt32(exam))
group result by result.category_tbl_ID into cat
select new { Group = cat , Count = cat.Count() } );
}

Related

An exception was thrown while attempting to evaluate a LINQ query parameter expression

I got error in the tittle. Probably i must control string.IsNullOrEmpty(searchString) but i didn't it. My code bellow. Please help me
Thank you everyone i solved this problem. Problem was not here. Prooblem in my route codes. for search is different i would write my route codes this
endpoints.MapControllerRoute(
name:"search",
pattern: "{search}",
defaults: new {controller="Shop",action="search"}
);
but not in from of pattern: "{search}
should be this pattern: "search"
Thank you to everyone who helped
public List<Product> GetSearchResult(string searchString)
{
using (var context = new ShopContext())
{
var products = context
.Products
.Where(i=> i.IsApproved && (i.Name.ToLower().Contains(searchString.ToLower()) || i.Description.ToLower().Contains(searchString.ToLower())))
.AsQueryable();
return products.ToList();
}
}
I would break this up as follows:
public List<Product> GetSearchResult(string searchString)
{
// What do you want to do if searchString is null or blank? (Pick one:)
// You could send back an empty result...
if (String.IsNullOrWhiteSpace(searchString))
return null;
// Or you could convert it to a blank string
if (searchString == null)
searchString = "";
List<Product> products = new List<Product>();
using (var context = new ShopContext())
{
products = context.Products.ToList();
}
// Always check for null and empty after going to the DB
if (products == null || products.count = 0)
return null;
// If we are still here, then we can finally do the search
List<Product> results = products.Where(i=> i.IsApproved &&
(i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
(i.Description != null && i.Description.ToLower().Contains(searchString.ToLower())));
return results;
}
Note: I've not tested this and there may be syntax errors in the last LINQ statement with all of the ('s and )'s.
EDIT:
The example above will pull back ALL records in the Product table and then filter the results in-memory. If you want to avoid that, then I think this should work:
public List<Product> GetSearchResult(string searchString)
{
// What do you want to do if searchString is null or blank? (Pick one:)
// You could send back an empty result...
if (String.IsNullOrWhiteSpace(searchString))
return null;
// Or you could convert it to a blank string
if (searchString == null)
searchString = "";
using (var context = new ShopContext())
{
List<Product> products = context.Products.Where(i=> i.IsApproved &&
(i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
(i.Description != null && i.Description.ToLower().Contains(searchString.ToLower()))).ToList();
return products;
}
}
The key difference between this and your OP is that we are checking for null's on Name and Description -- and I believe this does it in a way that EF can translate into a query.
Not a lot of information at hand but i assume the LINQ fails because a string is null.
Also why do you create a queryable of your results and then produce a list?
public List<Product> GetSearchResult(string searchString) {
static bool Contains(string a, string b) {
return a.ToLower().Contains(b.ToLower());
}
using (var context = new ShopContext()) {
return context
.Products
.Where(i => i.IsApproved)
.Where(i => i.Name is null ? false : Contains(i.Name, searchString)
|| i.Description is null ? false : Contains(i.Description, searchString))
.ToList();
}
}

Wildcard search in using Lambda in EF

I have a search with optional arguments:
string id1 = HttpContext.Current.Request["id1"];
string id2 = HttpContext.Current.Request["id2"];
List<Foo> list = context.Foo.Where(l =>
(string.IsNullOrEmpty(id1) || l.Id1.Contains(id1)) &&
(string.IsNullOrEmpty(id2) || l.Id2.Contains(id2)))
.Take(10)
.ToList());
I would like to extend it so that if the string starts with a *, the EndsWith() - method should be used.
For example, if the first searchstring is *123, I want to do a l.Id1.EndsWith("123").
Is there any way to extend my current code, or should I use a different approach?
I'm quite sure if this is what you were intending, but you can break your logic up by using IQueryable(T). The query won't be executed until you try to use the collection.
public IList<Foo> Search(DbContext<Foo> context, string id1, string id2)
{
Func<Foo, bool> predicate = l =>
(string.IsNullOrEmpty(id1) || l.Id1.Contains(id1))
&& (string.IsNullOrEmpty(id2) || l.Id2.Contains(id2)));
IQueryable<Foo> list = context.Foo.Where(predicate);
if(id1.StartsWith("*") && id1.Length > 1)
{
var searchTerm = id1.Substring(1, id1.Length);
list = list.Where(l => l.EndsWith(searchTerm));
}
return list.Take(10).ToList(); // Execution occurs at this point
}
Building up the query:
public void BasicSearch(IQueryable<foo> list, string id1, string id2)
{
Func<Foo, bool> predicate = l =>
(string.IsNullOrEmpty(id1) || l.Id1.Contains(id1))
&& (string.IsNullOrEmpty(id2) || l.Id2.Contains(id2)));
list.Where(predicate);
}
public void WildcardSearch(IQueryable<Foo> list, string id1)
{
if(!id1.StartsWith("*") || id1.Length <= 1) return;
var searchTerm = id1.Substring(1, id1.Length);
list.Where(l => l.EndsWith(searchTerm));
}
IQueryable<Foo> list = context.Foo;
BasicSearch(list, id1, id2);
WildcardSearch(list, id1);
var result = list.Take(10); // Execution occurs at this point

entity framework Where method

i need some help in this , how do i write a where clause statement where i want to retrieve record based on 2 columns :
This is how i am trying to write in code :
public IList<Model.question> GetAll(string search , int search1)
{
IList<Model.question> lstQuestions = context.questions.ToList();
return lstQuestions.Where(a => a.TaskName.Contains(search) && p => p.ActivityID.Contains(search1)).ToList();
}
but there is an error with this statement .
----- ABOVE SOLVED ------------
Heres another problem :
public int GetMaxValue(string listTask , int listActivity)
{
int maxQNo = Convert.ToInt32(context.questions.Max(q => q.QuestionNo).Where(q.TaskName.Contains(listTask) && q.ActivityID == listActivity));
return maxQNo+1;
}
i get the error where q doesn't exist is current context , what i am trying to do here , is to get the max value of the column ( questionNo) where taskname = list task and activityid = list activity.
public IList<Model.question> GetAll(string search , int search1)
{
IList<Model.question> lstQuestions = context.questions.ToList();
return lstQuestions.Where(a => a.TaskName.Contains(search) && a.ActivityID==search1)).ToList();
}
Answer of new problem:
Add q => block in Where clause.
public int GetMaxValue(string listTask , int listActivity)
{
int maxQNo = Convert.ToInt32(context.questions.Max(q => q.QuestionNo)
.Where(q=>q.TaskName.Contains(listTask) &&
q.ActivityID.Contains(listActivity));
return maxQNo+1;
}

How to clear default select clause on IQueryable resultset

If I have a page class that returns an IQueryable result set like:
protected virtual IQueryable<EntityResult> GetEntities(ETBDataContext pContext)
{
return from e in pContext.Entities
where e.SectionId == SectionId && e.StatusCode == "Published"
orderby e.PublishDate descending
select new EntityResult
{
EntityId = e.Id,
Excerpt = e.Excerpt,
Name = e.Name,
PublishDate = e.PublishDate,
ShortDescription = e.ShortDescription
};
}
If I call this method in a inherited class, How can I clear the select and just get the ShortDescription?
public void IQueryable<EntityResult> GetResult(ETBDataContext pContext)
{
IQueryable<EntityResult> pQuery = base.GetEntities(pContext);
//right here: how can I just return the ShortDescription Only?
return pQuery;
}
I am using the default GetEntities() to do the standard select operation for default queries, but on some calls I would like to get just the specific data that I need.
Is this possible? are there other ways? Thanks in advance!!
You can try
pQuery = pQuery.Select(e => new EntityResult {
ShortDescription = e.ShortDescription
});
I'm pretty sure that this won't select the other columns.

Entity Random Select from DB C# MVC

Try to find the solution but i cant.
So problem is next one. I have the EDM model of database. I have a class with functions to get data from DB.
Like this:
public IQueryable<photos> FindUserPhotos(string userlogin)
{
return from m in db.photos
where m.userlogin == userlogin
select m;
}
How to get the Random 10 lines from DB?
I always use this method for get custom entity OrderBy(x => Guid.NewGuid())
public photos Find10RandomUserPhotos(string userlogin)
{
return db.photos.Where(x => x.userlogin == userlogin).OrderBy(x => Guid.NewGuid()).Take(10).ToList();
}
Following Random row from Linq to Sql
public photos FindRandomUserPhoto(string userlogin)
{
var qry = FindUserPhotos(userlogin);
int count = qry.Count();
int index = new Random().Next(count);
return qry.Skip(index).FirstOrDefault();
}
public Array<photos> Find10RandomUserPhotos(string userlogin)
{
var result = New Array<photos>;
for (i = 0; i < 10; i++) {
result.add(FindRandomUserPhoto(userlogin));
}
return result
}

Categories