web-dev-qa-db-ja.com

LINQ to SQL:GroupBy()およびMax()で最新の日付のオブジェクトを取得

監査用のイベントを格納するために使用される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) 

Custs Layout

質問:AccessDateの最新(最大CustID)レコード/オブジェクトを選択するクエリを作成するにはどうすればよいですか?

37
p.campbell

私は次のようなものかどうか疑問に思っています:

_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();
_

OrderBy()Last()を試すこともできます

36
Marc Gravell

LINQ構文を使用すると、見た目がすっきりします。

var custsLastAccess = from c in db.CustAccesses 
                      group c by c.CustID into grp
                      select grp.OrderByDescending(c => c.AccessDate).FirstOrDefault();
27
CodeGrue

ここでは、OrderByDescではなくmaxを使用しているため、より効率的です。

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;
5
Gary
var custsLastAccess = db.CustAccesses   
                            .Where(c.AccessReason.Length>0)
                        .GroupBy(c => c.CustID, (id, custs) => new { ID=id, LastAccess=custs.OrderByDescending(c=>c.AccessDate).First().AccessDate})
                      .Select()
                        .ToList();
0
vladhorby