我有一个 Case
对象和一个 Property
对象,这样一个 Property 可以有多个 Case:Case 对象有一个 PropertyId
属性。
我只想检索每个属性的最新案例,因此我尝试使用 GroupBy
以避免 n+1 查询问题:
private IQueryable<Case> AllActiveCases()
=> _context.Cases.Where(c => c.DeletedAt == null);
...
var result = await AllActiveCases()
.GroupBy(c => c.PropertyId)
.SelectMany(cases => cases.OrderByDescending(c => c.CreatedAt).Take(1))
.AsNoTracking()
.ToListAsync(cancellationToken);
但是,这给了我
System.InvalidOperationException: 'The LINQ expression 'DbSet<Case>()
.Where(c => c.DeletedAt == null)
.GroupBy(c => c.PropertyId)
.SelectMany(cases => cases
.AsQueryable()
.OrderByDescending(c => c.CreatedAt)
.Take(1))' 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', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
我使用的是 EF Core 7.0.1。
我已经检查了不受支持的 Linq 方法 ( https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities?redirectedfrom=MSDN ),但似乎没有使用任何错误。
最佳答案
将Select
与First
一起使用:
var result = await AllActiveCases()
.GroupBy(c => c.PropertyId)
.Select(cases => cases.OrderByDescending(c => c.CreatedAt).First())
.AsNoTracking()
.ToListAsync(cancellationToken);
另一种方法(如果您需要组中的多个条目)是展平客户端:
var resultTmp = await AllActiveCases()
.GroupBy(c => c.PropertyId)
.Select(cases => cases.OrderByDescending(c => c.CreatedAt).Take(5))
.AsNoTracking()
.ToListAsync(cancellationToken);
var result = resultTmp.SelectMany(t => t).ToList();
关于entity-framework - 无法翻译 EF Linq GroupBy 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76771327/