LINQ с помощью Max () для выбора одной строки
Я использую LINQ на IQueryable, возвращенном из NHibernate, и мне нужно выбрать строку с максимальным значением(ами) в нескольких полях.
я упростил бит,который я придерживаюсь. Мне нужно выбрать одну строку из моей таблицы с максимальным значением в одном поле.
var table = new Table { new Row(id: 1, status: 10), new Row(id: 2, status: 20) }
from u in table
group u by 1 into g
where u.Status == g.Max(u => u.Status)
select u
Это неправильно, но я не могу выработать правильную форму.
кстати, то, что я на самом деле пытаюсь достичь, примерно так:
var clientAddress = this.repository.GetAll()
    .GroupBy(a => a)
    .SelectMany(
            g =>
            g.Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.AddressReference == g.Max(x => x.AddressReference) && 
                a.StartDate == g.Max(x => x.StartDate)))
    .SingleOrDefault();
Я начал с выше лямбда, но я использую LINQPad, чтобы попытаться разработать синтаксис для выбора Max().
обновление
удаление GroupBy было ключевым.
var all = this.repository.GetAll();
var address = all
            .Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.StartDate == all.Max(x => x.StartDate) &&
                a.AddressReference == all.Max(x => x.AddressReference))
            .SingleOrDefault();
5 ответов:
Я не понимаю, почему вы группировку здесь.
попробуйте это:
var maxValue = table.Max(x => x.Status) var result = table.First(x => x.Status == maxValue);альтернативный подход, который будет итерировать
tableтолько один раз будет это:var result = table.OrderByDescending(x => x.Status).First();это полезно, если
tableэтоIEnumerable<T>чего нет в памяти или что вычисляется на лету.
вы можете сгруппировать по статусу и выбрать строку из самой большой группы:
table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();первый
First()получает первую группу (набор строк с наибольшим статусом); втораяFirst()получает первую строчку в этой группе.
Если статус всегда unqiue, вы можете заменить второйFirst()СSingle().
обращаясь к первому вопросу, если вам нужно занять несколько строк, сгруппированных по определенным критериям, с другой столбец с максимальным значением вы можете сделать что-то вроде этого:
var query = from u1 in table join u2 in ( from u in table group u by u.GroupId into g select new { GroupId = g.Key, MaxStatus = g.Max(x => x.Status) } ) on new { u1.GroupId, u1.Status } equals new { u2.GroupId, Status = u2.MaxStatus} select u1;