LINQ to SQL:GroupBy()和Max()获取具有最新日期的对象

p.c*_*ell 34 c# linq group-by linq-to-sql

考虑一个用于存储审计事件的SQL Server表.

需要的是只获得每个CustID的最新条目.我们想要获得整个对象/行.我假设在查询中需要GroupBy().这是迄今为止的查询:

var custsLastAccess = db.CustAccesses   
                        .Where(c.AccessReason.Length>0)
                        .GroupBy(c => c.CustID)
//                      .Select()
                        .ToList();
// (?) where to put the c.Max(cu=>cu.AccessDate) 
Run Code Online (Sandbox Code Playgroud)

客户布局

问题: 如何创建查询以选择每个的最新(最大AccessDate)记录/对象CustID

Mar*_*ell 35

我想知道是否有类似的东西:

var custsLastAccess = db.CustAccesses   
                    .Where(c.AccessReason.Length>0)
                    .GroupBy(c => c.CustID)
                    .Select(grp => new {
                      grp.Key,
                      LastAccess = grp
                         .OrderByDescending(x => x.AccessDate)
                         .Select(x => x.AccessDate)
                         .FirstOrDefault()
                    }).ToList();
Run Code Online (Sandbox Code Playgroud)

你也可以尝试OrderBy()Last()


Cod*_*rue 23

使用LINQ语法,我觉得它看起来更干净:

var custsLastAccess = from c in db.CustAccesses 
                      group c by c.CustID into grp
                      select grp.OrderByDescending(c => c.AccessDate).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)


Gar*_*ary 6

这里:这使用 max 而不是 OrderByDesc,所以应该更有效。

var subquery = from c in CustAccesses
            group c by c.CustID into g
            select new
            {
                CustID = g.Key,
                AccessDate = g.Max(a => a.AccessDate)
            };
var query = from c in CustAccesses
            join s in subquery 
              on c.CustID equals s.CustID
            where c.AccessDate == s.AccessDate
             && !string.IsNullOrEmpty(c.AccessReason)
            select c;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不会打破联系 - 如果有两行具有相同的 CustID 和相同的 AccessDate,它们都将在连接中找到,并且您可能最终会得到每个客户 ID 的多个“最近访问”。 (2认同)