LINQ使用Max()选择单行

Bog*_*gin 90 .net c# linq

我在从NHibernate返回的IQueryable上使用LINQ,我需要在几个字段中选择具有最大值的行.

我简化了我坚持的一点点.我需要从表中选择一行,并在一个字段中使用最大值.

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
Run Code Online (Sandbox Code Playgroud)

这是不正确的,但我无法找到正确的表格.

顺便说一下,我实际上想要实现的是这样的:

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();
Run Code Online (Sandbox Code Playgroud)

我从上面的lambda开始,但我一直在使用LINQPad来尝试找出选择Max()的语法.

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();
Run Code Online (Sandbox Code Playgroud)

Dan*_*rth 215

我不明白你为什么要在这里分组.

试试这个:

var maxValue = table.Max(x => x.Status)
var result = table.First(x => x.Status == maxValue);
Run Code Online (Sandbox Code Playgroud)

另一种table只迭代一次的方法是:

var result = table.OrderByDescending(x => x.Status).First();
Run Code Online (Sandbox Code Playgroud)

这是有益的,如果table是一个IEnumerable<T>未在内存中存在,或者是实时计算.

  • @LandonPoch:这不是一个好主意,因为这将计算最大N次,其中N是`table`中的项目数. (12认同)
  • @Daniel Hilgarth:好抓!实际上,这将计算表中每行的最大值.我的错. (2认同)

小智 15

你也可以这样做:

(from u in table
orderby u.Status descending
select u).Take(1);
Run Code Online (Sandbox Code Playgroud)


SLa*_*aks 13

您可以按状态分组并从最大的组中选择一行:

table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();
Run Code Online (Sandbox Code Playgroud)

第一个First()获取第一个组(具有最大状态的行集); 第二个First()获取该组中的第一行.
如果状态总是unqiue,可以更换第二First()Single().


Dmi*_*min 7

解决第一个问题,如果您需要按照某些条件对多行进行分组,而另一列具有最大值,则可以执行以下操作:

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;
Run Code Online (Sandbox Code Playgroud)