You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 5使用GroupBy取分组最新行遇无法翻译异常如何解决

EF Core 5 分组取最新行可翻译查询写法

EF Core 5 不支持直接对GroupBy返回的分组集合执行内部排序、取元素操作的SQL翻译,你可以改用窗口函数ROW_NUMBER的思路实现需求,该写法可完全被翻译为SQL在数据库端执行,无客户端评估性能损耗:

var entries = await _dbContext.MyTable
    .Select(s => new 
    {
        Entity = s,
        RowNumber = EF.Functions.RowNumber()
            .Over(partition => partition
                .PartitionBy(s => s.Something)
                .OrderByDescending(s => s.CreatedDate))
    })
    .Where(s => s.RowNumber == 1)
    .Select(s => s.Entity)
    .ToListAsync();

注意事项

  • 上述写法生成的SQL等价于原生SQL:
    SELECT * FROM (
        SELECT *, ROW_NUMBER() OVER(PARTITION BY Something ORDER BY CreatedDate DESC) AS rn 
        FROM MyTable
    ) t WHERE rn = 1
    
    性能和手写原生SQL完全一致。
  • 如果同一分组内存在多条CreatedDate完全相同的记录,该写法只会返回其中一条,和你原写法的First()语义完全匹配。

兼容低版本EF Core可选方案

如果需要适配不支持窗口函数翻译的更低版本EF Core,可使用先查分组最大时间再关联的写法:

// 先查询每个分组的最大创建时间
var groupMaxDateQuery = _dbContext.MyTable
    .GroupBy(s => s.Something)
    .Select(g => new 
    {
        GroupKey = g.Key,
        MaxDate = g.Max(s => s.CreatedDate)
    });

// 关联原表取对应记录
var entries = await _dbContext.MyTable
    .Join(groupMaxDateQuery,
        original => new { original.Something, original.CreatedDate },
        group => new { Something = group.GroupKey, CreatedDate = group.MaxDate },
        (original, group) => original)
    .ToListAsync();

该方案如果同一分组内存在多条时间等于最大值的记录,会全部返回,和First()语义有差异,需要根据业务场景选择使用。

内容的提问来源于stack exchange,提问作者Milos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:27:01