Is there a proper way to do Count of child items of an entity and filter by this value
The way i'm trying to do it right now
var seed = context.Items.Select(x => new {
count = x.ChildItems.Count()
};
seed = seed.Where(x => x.count > 0);
As a result I see in logs that
The LINQ expression '...' could not be translated and will be evaluated locally.
And it will create count query for each row!!
Am i doing something wrong or this is not possible in EF CORE 2.1
What's wrong with the following:
var seed = context.Items.Include(x => x.ChildItems).Where(x => x.ChildItems.Count() > 0).ToList();
Related
This question already has an answer here:
How to select top N rows for each group in a Entity Framework GroupBy with EF 3.1
(1 answer)
Closed 1 year ago.
I'm trying to retrieve the latest row in a group base on the CreatedDate field.
How can this query be rewritten for EF Core 5 in a way which is not going to throw this Exception?
".OrderByDescending(s => s.CreatedDate)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable'"?
Inserting AsEnumerable works, but this would be terrible solution.
var entries = _dbContext.MyTable
.GroupBy(s => s.Something)
.Select(g => g.OrderByDescending(s => s.CreatedDate).First())
.ToListAsync();
Faster solution is via ROW_NUMBER function. But you can create workaround:
var mainQuery = _dbContext.MyTable;
var query =
from d in mainQuery.Select(s => new {s.Something}).Distinct()
from x in mainQuery.Where(x => x.Something == d.Something)
.OrderByDescending(x.CreateDate)
.Take(1)
select x;
var result = await query.ToListAsync();
I am trying to build a query using asp.net core c#
https://www.reflectionit.nl/blog/2017/paging-in-asp-net-core-mvc-and-entityframework-core
I trying to do a filtering however I need the data from another table which have my unique id
var result = _context.UserRoles.Where(y => y.RoleId.Contains(selectedRoles.Id)); // Retrieve the the userid i have from another table with the selected roleid
var query = _context.Users.Where(x => //I have already tried contains, where join );
If there is a site where i can learn this query please recommend. "Join()" does not work as I am doing paging
a least two solutions (please note that I do not check the identity classes members, so the following is the "spirit" of the solution (you miss the select clauses) ):
var result = _context.UserRoles.
Where(y => selectedRoles.Contains(y.RoleId)).
Select(y => y.User);
or
var result = _context.UserRoles.
Where(y => selectedRoles.Contains(y.RoleId)).
Select(y => y.UserId);
query = _context.Users.
Where(x => result.Contains(x.Id));
That said, assuming that there is no UserRoles table exposed in Identity (v2), you probably want:
userManager.Users.
Where(u => u.Roles.Any(r => selectecRoles.Contains(r.RoleId)));
Up to you to instanciate the userManager.
I'm trying to count some records that were updated this week and group them by the day of week (depending when they were last updated). E.g.So Tues:1, Thur:4 Fri:5 etc... I'm not sure how to group by day of week.
var data = repo
.Where(o => o.LastUpdated >= monday)
.GroupBy(o => o.LastUpdated)
.Select(g => new { DayOfWeek = g.Key, Count = g.Count() })
.ToList();
I've tried .GroupBy(o => o.LastUpdated.DayOfWeek but that throws an error :
"The specified type member 'DayOfWeek' is not supported in LINQ to Entities"
If you are targeting only SqlServer database type, you can use SqlFunctions.DatePart canonical function like this
var data = repo
.Where(o => o.LastUpdated >= monday)
.GroupBy(o => SqlFunctions.DatePart("weekday", o.LastUpdated))
.Select(g => new { DayOfWeek = g.Key, Count = g.Count() })
.ToList();
Unfortunately there is no such general canonical function defined in DbFunctions, so if you are targeting another database type (or multiple database types), the only option is to switch to Linq To Objects context as described in another answer.
The message is explicit, Entity Framework doesn't know how to translate "DayOfWeek" to SQL. The simplest solution would be to do the grouping outside of SQL after retrieving the data:
var data = repo
.Where(o => o.LastUpdated >= monday)
.AsEnumerable() // After this everything uses LINQ to Objects and is executed locally, not on your SQL server
.GroupBy(o => o.LastUpdated)
.Select(g => new { DayOfWeek = g.Key, Count = g.Count() })
.ToList();
It should hardly have a performance impact either way as you're not filtering further down so you're not retrieving more data than you need from the server, anything past AsEnumerable is materialized as data, anything before just générâtes a SQL query, so past AsEnumerable (or anything else that would materialize the query like ToArray or ToList) you can use anything you'd normally use in C# without worrying about it being translatable to SQL.
It is only possible to lastupdated column datatype of datetime.
var data = repo.Where(o => o.LastUpdated >= monday).AsEnumerable().GroupBy(o => o.LastUpdated.Value.Day).Select(g => new { DayOfWeek = g.Key, Count = g.Count() }).ToList();
I want to fetch the candidate and the work exp where it is not deleted. I am using repository pattern in my c# app mvc.
Kind of having trouble filtering the record and its related child entities
I have list of candidates which have collection of workexp kind of throws error saying cannot build expression from the body.
I tried putting out anonymous object but error still persist, but if I use a VM or DTO for returning the data the query works.
It's like EF doesn't like newing up of the existing entity within its current context.
var candidate = dbcontext.candidate
.where(c=>c.candiate.ID == id).include(c=>c.WorkExperience)
.select(e=>new candidate
{
WorkExperience = e.WorkExperience.where(k=>k.isdeleted==false).tolist()
});
Is there any workaround for this?
You cannot call ToList in the expression that is traslated to SQL. Alternatively, you can start you query from selecting from WorkExperience table. I'm not aware of the structure of your database, but something like this might work:
var candidate = dbcontext.WorkExperience
.Include(exp => exp.Candidate)
.Where(exp => exp.isdeleted == false && exp.Candidate.ID == id)
.GroupBy(exp => exp.Candidate)
.ToArray() //query actually gets executed and return grouped data from the DB
.Select(groped => new {
Candidate = grouped.Key,
Experience = grouped.ToArray()
});
var candidate =
from(dbcontext.candidate.Include(c=>c.WorkExperience)
where(c=>c.candiate.ID == id)
select c).ToList().Select(cand => new candidate{WorkExperience = cand.WorkExperience.where(k=>k.isdeleted==false).tolist()});
how to select distinct with paging in entity framework?
i try to code below
var ll = _ctx.Cwzz_AccVouchMain.Select(v => v.Ddate).Distinct();
var l = ll.Skip(start).Take(limit).ToList();
but error:
must call orderBy method before skip
but my try
var ll = _ctx.Cwzz_AccVouchMain.Select(v => v.Ddate).Distinct();
var l = ll.OrderBy(v => v.Year).ThenBy(v => v.Month).ThenBy(v => v.Date).Skip(start).Take(limit).ToList();
error
ystem.NotSupportedException: LINQ to Entities not suppor type of "Date”。only support initial settlement,entity memeber,entity navagation property.
how to do?
Try this instead :
var ll = _ctx.Cwzz_AccVouchMain.Select(v => v.Ddate).Distinct();
var l = ll.OrderBy(v => v).Skip(start).Take(limit).ToList();
When you try to order by year, month and date, your query is not yet executed, and when .ToList() triggers it, it tries to build the appropriate sql query before sending it to your database server. However, your db has no clue about a Ddate.Year, Ddate.Month or Ddate.Date, because on the db side the Ddate field is a simple date, he doesn't understand your object with properties like the DateTime you use in C#.
If you wanted to order by month only (for example), you would have to trigger your query before that.