LINQ Using Max() to select a single row
I'm using LINQ on an IQueryable returned from NHibernate and I need to select the row with the maximum value(s) in a couple of fields.
I've simplified the bit that I'm sticking on. I need to select the one row from my table with the maximum value in one field.
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
This is incorrect but I can't work out the right form.
BTW, what I'm actually trying to achieve is approximately this:
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();
I started with the above lambda but I've been using LINQPad to try and work out the syntax for selecting the Max().
UPDATE
Removing the GroupBy was key.
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();
I don't see why you are grouping here.
Try this:
var maxValue = table.Max(x => x.Status)
var result = table.First(x => x.Status == maxValue);
An alternate approach that would iterate table
only once would be this:
var result = table.OrderByDescending(x => x.Status).First();
This is helpful if table
is an IEnumerable<T>
that is not present in memory or that is calculated on the fly.
You can also do:
(from u in table
orderby u.Status descending
select u).Take(1);
You can group by status and select a row from the largest group:
table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();
The first First()
gets the first group (the set of rows with the largest status); the second First()
gets the first row in that group.
If the status is always unqiue, you can replace the second First()
with Single()
.