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

.NET Core中Linq GroupBy与OrderByDescending无法转换问题求助

解决.NET Core 3.1中GroupBy后OrderByDescending无法转换的问题

问题出在EF Core 3.1对LINQ查询的翻译逻辑比旧版.NET Framework的EF更严格——你原代码里在GroupBy后的Select中直接对组内数据排序取第一条的写法,没法被转换成数据库能执行的SQL,所以报错。

给你两种可行的解决办法:

方案一:用窗口函数(ROW_NUMBER)

通过窗口函数给每个deviceId分组内的记录按Time降序编号,然后取编号为1的记录,这种写法能被EF Core 3.1正确翻译:

var prevlist = _db.Botstatus
    .Where(x => x.Time < starttime && x.Status != null)
    .Select(x => new 
    {
        x,
        RowNum = EF.Functions.RowNumber()
            .Over(partitionBy: x.deviceId, orderBy: x.Time descending)
    })
    .Where(r => r.RowNum == 1)
    .Select(r => r.x)
    .ToList();

方案二:先取每组最大Time再关联原表

先查出每个deviceId对应的最大Time,再通过deviceId和Time关联原表拿到对应记录,兼容性更好:

// 先获取每个设备的最新有效时间
var maxTimePerDevice = _db.Botstatus
    .Where(x => x.Time < starttime && x.Status != null)
    .GroupBy(x => x.deviceId)
    .Select(g => new 
    {
        DeviceId = g.Key,
        MaxTime = g.Max(x => x.Time)
    });

// 关联原表拿到对应记录
var prevlist = _db.Botstatus
    .Join(maxTimePerDevice,
        bot => new { bot.deviceId, bot.Time },
        time => new { time.DeviceId, time.MaxTime },
        (bot, time) => bot)
    .ToList();

注意:如果同一个deviceId和Time对应多条记录,方案二会返回多条,这时候可以在Join后加额外过滤或者结合FirstOrDefault处理;方案一则只会返回每组里Time最新的那一条,更精准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:54:18