通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录

Posted

技术标签:

【中文标题】通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录【英文标题】:group by linq to entity query to get one record having latest timestamp by joining tables 【发布时间】:2021-05-21 23:21:52 【问题描述】:

有两个表并使用 linq 查询来获取记录。从第二个表中,可以有多行对应于具有日期时间戳的第一个表...基于以下查询,我正在获取所有记录,但是有没有办法我们可以从具有最新时间戳的第二个表中获取行?

Table Parent

ID            Name    
1              M            
2              N             
3              O
4              P
5              Q

Table Child
Id            fkID        DateTime
1              2              01/12/2021 09:12:20
2              2              01/12/2021 09:13:20
3              2              01/12/2021 09:14:20
4              2              01/12/2021 09:15:20
5              2              01/12/2021 **09:16:20**

Linq 查询:

from p in Parent
join c in Child on p.id equals c.fkId into cJoin
from cJoin in cJoin.DefaultIfEmpty()
select new TempResponse

Id = p.Id,
Name = p.Name,
Date = c.Date


I am getting 10 records using above query but just need 5 records i.e. from child table instead of all 5 records, we need a record that has latest time stamp
 
**expected output**
1              M
2              N             01/12/2021 09:16:20 
this record is 5'th record from child table because this one has latest date time stamp 
( latest record )
3              O
4              P
5              Q

有什么方法可以使用 group by 并从第二个表中获取具有最新时间戳的记录?

【问题讨论】:

你提到了linq,但这实际上是实体框架吗?还是纯粹在记忆中? 添加了缺失的标签。我正在使用实体框架并使用上述查询来获取数据 【参考方案1】:

我相信你可以使用:

var ans = from p in Parent
          join cmax in (
            from c in Child
            group c by c.fkId into cg
            select cg.OrderByDescending(c => c.Date).FirstOrDefault())
          on p.Id equals cmax.fkId into cJoin
          from c in cJoin.DefaultIfEmpty()
          select new TempResponse 
              Id = p.Id,
              Name = p.Name,
              Date = c != null ? c.Date : null
          ;

请注意,SQL Server 上的结果顺序似乎有所不同,除非您在 select 之前添加另一个 orderby 子句以强制排序。

【讨论】:

【参考方案2】:

假设您已经为 FK 定义了导航属性,我会使用类似的查询;

dbContext.Child.Where(c => c.Date == c.Parent.Child.Max(c2 => c2.Date))

【讨论】:

以上是关于通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 .NET Core 进行分组的 Linq 查询

实体框架 LINQ - 具有分组依据的子查询

Linq善解人意之通过MSDN对14个“查询关键字“逐个解剖

LINQ查询表达式 - LINQ 查询分组

无法使用 Nhibernate 的 Linq 检索 Group By 实体或复合键

如何通过循环 db [C# MVC & LINQ] 中的 3 个表来映射数据以对应表头