Подтвердить что ты не робот

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?

4b9b3361

Ответ 1

Мне интересно, если что-то вроде:

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

вы также можете попробовать OrderBy() и Last()

Ответ 2

Использование синтаксиса LINQ, который, как мне кажется, выглядит более чистым:

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

Ответ 3

Здесь: используется 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;

Ответ 4

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