如何解决EF Core Linq按ImageId分组取每组最高分的报错问题
报错原因
EF Core 的 LINQ 转译器不支持 GroupBy 操作完成后直接对分组内的元素集合进行排序、取首条这类操作,无法生成对应的 SQL 语句,因此抛出无法转译的异常。
解决方案
方案1:数据库端执行(推荐,适合所有数据量场景)
改写查询逻辑,先取每个分组的最高分,再关联原表匹配完整记录,该写法可被EF Core正常转译为SQL,所有运算在数据库执行,性能更优:
public async Task<List<HistoryEntry>> Handle(Request request, CancellationToken cancellationToken) { return await _db.History .GroupBy(h => h.ImageId) .Select(g => new { ImageId = g.Key, MaxScore = g.Max(h => h.Score) }) .Join(_db.History, left => new { left.ImageId, Score = left.MaxScore }, right => new { right.ImageId, right.Score }, (_, history) => history) .ToListAsync(cancellationToken); }
方案2:客户端内存执行(仅适合小表场景)
先将全表数据加载到内存,再在内存中做分组排序取数,仅适合表数据量极小的场景,数据量大时会出现严重的内存占用和性能问题:
public async Task<List<HistoryEntry>> Handle(Request request, CancellationToken cancellationToken) { return await _db.History .AsAsyncEnumerable() .GroupBy(a => a.ImageId) .Select(s => s.OrderByDescending(x => x.Score).First()) .ToListAsync(cancellationToken); }
内容的提问来源于stack exchange,提问作者Marsh Mellow
相关产品推荐
相关产品推荐

