Estou usando o LINQ em um IQueryable retornado do NHibernate e preciso selecionar a linha com o (s) valor (es) máximo (s) em alguns campos.
Simplifiquei a parte que estou insistindo. Preciso selecionar uma linha da minha tabela com o valor máximo em um campo.
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
Isso está incorreto, mas não consigo descobrir a forma correta.
BTW, o que estou tentando alcançar é aproximadamente isso:
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();
Comecei com o lambda acima, mas tenho usado o LINQPad para tentar descobrir a sintaxe para selecionar Max ().
ATUALIZAR
Remover o GroupBy foi fundamental.
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();
Respostas:
Não vejo por que você está agrupando aqui.
Experimente isto:
Uma abordagem alternativa que iteraria
table
apenas uma vez seria esta:Isso é útil se
table
for umIEnumerable<T>
que não está presente na memória ou que é calculado rapidamente.fonte
from u in User_Accounts where u.Status == User_Accounts.Max(y => y.Status) select u
table.First(x => x.Status == table.Max(x => x.Status))
table
.Você também pode fazer:
fonte
Você pode agrupar por status e selecionar uma linha do maior grupo:
O primeiro
First()
obtém o primeiro grupo (o conjunto de linhas com o maior status); o segundoFirst()
obtém a primeira linha desse grupo.Se o status for sempre unqiue, você pode substituir o segundo
First()
porSingle()
.fonte
Respondendo à primeira questão, se você precisar pegar várias linhas agrupadas por certos critérios com a outra coluna com valor máximo, você pode fazer algo assim:
fonte
Mais um exemplo:
Segue:
É igual a:
fonte
Simplesmente em uma linha:
Observe que existem duas ações. a ação interna é para encontrar o valor máximo, a ação externa é para obter o objeto desejado.
fonte