LINQ使用Max()来select一行
我在从NHibernate返回的IQueryable上使用LINQ,我需要在几个字段中select具有最大值的行。
我简化了我坚持的一点。 我需要从我的表中select一个字段中的最大值的一行。
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
这是不正确的,但我不能找出正确的forms。
顺便说一下,我实际上试图达到的是这样的:
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();
我从上面的lambda开始,但是我一直在使用LINQPad来试着找出selectMax()的语法。
UPDATE
删除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();
我不明白你为什么在这里分组。
尝试这个:
var maxValue = table.Max(x => x.Status) var result = table.First(x => x.Status == maxValue);
只有一次迭代表的替代方法是:
var result = table.OrderByDescending(x => x.Status).First();
如果table
是一个IEnumerable<T>
,它不在内存中,或者是在运行时计算的,这会很有帮助。
您可以按状态进行分组,并从最大的组中select一行:
table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();
第一个First()
得到第一个组(状态最大的一组行); 第二个First()
获取该组中的第一行。
如果状态始终不一致,则可以用Single()
replace第二个First()
Single()
。
你也可以这样做:
(from u in table orderby u.Status descending select u).Take(1);
解决第一个问题,如果你需要按照一定的标准分组,按照最大值的其他列,你可以做这样的事情:
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;
只需一行:
var result = table.First(x => x.Status == table.Max(y => y.Status));
注意有两个动作。 内部动作是为了find最大值,外部动作是为了得到想要的对象。