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
?
Ответы
Ответ 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();