.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
相关产品推荐
相关产品推荐

