LINQ使用Max()选择一行
本文关键字:一行 选择 使用 LINQ Max | 更新日期: 2023-09-27 18:22:10
我在从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
这是不正确的,但我无法算出正确的表格。
顺便说一句,我实际上试图实现的大致是:
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来尝试和计算选择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();
我不明白你为什么在这里分组。
试试这个:
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>
,或者是动态计算的,则这很有帮助。
您还可以执行:
(from u in table
orderby u.Status descending
select u).Take(1);
您可以按状态分组,并从最大的组中选择一行:
table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();
第一个First()
得到第一组(具有最大状态的行的集合);第二CCD_ 5获得该组中的第一行
如果状态始终为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;
使用Aggregate
怎么样?
它比更好
- 选择最大值
- 按最大值选择
因为它只扫描阵列一次。
var maxRow = table.Aggregate(
(a, b) => a.Status > b.Status ? a : b // whatever you need to compare
);
还有一个例子:
关注:
qryAux = (from q in qryAux where
q.OrdSeq == (from pp in Sessao.Query<NameTable>() where pp.FieldPk
== q.FieldPk select pp.OrdSeq).Max() select q);
等于:
select t.* from nametable t where t.OrdSeq =
(select max(t2.OrdSeq) from nametable t2 where t2.FieldPk= t.FieldPk)
简单地在一行中:
var result = table.First(x => x.Status == table.Max(y => y.Status));
请注意,有两个动作。内部动作是为了找到最大值,外部动作是为了得到想要的对象。