2009-11-10 112 views
27

監査用のイベントを格納するために使用されるSQL Serverテーブルについて考えてみましょう。LINQ to SQL:最新の日付のオブジェクトを取得するGroupBy()およびMax()

各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

質問: はどのように私は、各CustIDの最新(最大AccessDate)レコード/オブジェクトを選択するクエリを作成することができますか?

答えて

26

のようなものならば、私は思ったんだけど:

var custsLastAccess = from c in db.CustAccesses 
         group c by c.CustID into grp 
         select grp.OrderByDescending(c => c.AccessDate).FirstOrDefault(); 
0
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(); 
18

を試みることができますここでは、これは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; 
3

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

あなたはまた、私はきれいに見えると思うLINQの構文を使用してOrderBy()Last()

+1

これは関係を壊さないことに注意してください - 同じお客様IDと同じAccessDAteを持つ2つの行が存在する場合、それらは両方の参加に記載されています、そしてあなたは、複数の「最近のアクセスに終わるかもしれません"顧客IDごとに。 –

関連する問題