首页 > 解决方案 > 使用linq获取group by中最新记录的id

问题描述

我正在尝试获取 linq 中某个组的最新记录,但我想要的是 id,而不是日期,因为有时日期可能与其他记录完全相同。

以下代码为我提供了密钥和最后日期

var latestPositions = from bs in Scan
     group bs by bs.Asset into op
     select new
     {
        Asset = op.Key,
        LastSeen = op.Max(x => x.LastSeen)
      };

返回这样的东西......

资产 LastSeen
BS1 2020-05-10
BS2 2020-07-10

这是我需要的,但是我需要从该表行中获取其余数据,但是如果我在两列上加入它,我可以获得多行,有没有办法让我返回 id 列group by,所以我可以加入吗?

谢谢

标签: c#linqlinq-to-sqlentity-framework-core

解决方案


由于 SQL 限制,GroupBy 在这里无法提供帮助。但是您可以编写解决方法

var latestPositions = from bs in Scan
   where !Scan.Any(s => s.Asset == bs.Asset && s.LastSeen > bs.LastSeen)
   select bs;

但我不得不提一下,最快的方法是使用 EF Core 中不可用的窗口函数:

SELET 
   sc.Id
FROM (
   SELECT 
      s.Id,
      ROW_NUMBER() OVER (PARTITION BY s.Asset ORDER BY s.LastSeen DESC) AS RN
   FROM Scan s
) sc
WHERE sc.RN == 1

但是存在 EF Core 扩展linq2db.EntityFrameworkCore这使得通过 LINQ 成为可能(我假设 Asset 只是 ID,而不是导航属性)

var queryRn = from bs in Scan
   select new 
   {
      Entity = bs,
      RN = Sql.Ext.RowNumber().Over()
        .PartitionBy(bs.Asset).OrderByDesc(bs.LastSeen).ToValue()
   };

 // switch to alternative translator
 queryRn = queryRn.ToLinqToDB();

 var latestPositions = from q in queryRn
    where q.RN == 1
    select q.Entity;

推荐阅读