Observe como você pode usar o mesmo nome toda vez. Isso também é equivalente a:
tmp =from o in invoices.InvoiceCollectionorderby o.InvoiceOwner.LastName,
o.InvoiceOwner.FirstName,
o.InvoiceIDselect o;
Se você ligar OrderByvárias vezes, ele efetivamente reordenará a sequência completamente três vezes ... para que a chamada final seja efetivamente a dominante. Você pode (no LINQ to Objects) escrever
foo.OrderBy(x).OrderBy(y).OrderBy(z)
o que seria equivalente a
foo.OrderBy(z).ThenBy(y).ThenBy(x)
como a ordem de classificação é estável, mas você absolutamente não deve:
É difícil de ler
Não funciona bem (porque reordena toda a sequência)
Pode não funcionar em outros provedores (por exemplo, LINQ to SQL)
Basicamente, não é como OrderByfoi projetado para ser usado.
O objetivo de OrderByé fornecer a projeção de pedidos "mais importante"; use ThenBy(repetidamente) para especificar projeções secundárias, terciárias, etc.
Efetivamente, pense dessa maneira: OrderBy(...).ThenBy(...).ThenBy(...)permite criar uma única comparação composta para dois objetos e, em seguida, classifique a sequência uma vez usando essa comparação composta. Isso é quase certamente o que você deseja.
Foi o que pensei, mas, por algum motivo, o OrderBy, ThenBy, ThenBy não parece estar sendo classificado corretamente, então eu me perguntei se o estava usando corretamente.
DazManCat
14
Observe que, na sintaxe da consulta, a palavra-chave para pedidos é realmente orderby, não order by. ( Desculpe pelo pedantismo - só queria dizer uma vez eu corrigi um post Jon Skeet )
fostandy
1
Jon, algo não se encaixa para mim na seção, mas você absolutamente não deve (que se refere à aplicação de ordens múltiplas usando a sintaxe fluq do linq, uma vez que se traduz em ThenBy, em consultas locais): Ele não funciona bem (porque reordena a sequência inteira) - você quer dizer a 2ª ou a 3ª ordem reordenando a sequência inteira? se sim, como ainda será traduzido para o ThenBy depois de ter reordenado a sequência descartando a ordem anterior?
Veverke 9/08/16
@Veverke: Reordena toda a sequência, mas de maneira estável, portanto, se dois valores tiverem o mesmo valor z, a ordem dependerá de y e, em seguida, de x.
Jon Skeet
1
@Veverke: OrderBy(a).OrderBy(b).OrderBy(c)ainda usa a saída da classificação anterior e reordena a coisa toda, mas preserva a ordem existente (da etapa anterior) em que dois elementos são iguais na nova comparação. Imagine que apenas temos OrderBy(a).OrderBy(b). Os resultados de OrderBy(a)estão em aordem crescente e, em seguida, são reordenados de acordo com b. No resultado final, se dois valores tiverem o mesmo bvalor, eles serão ordenados adevido à classificação ser estável - portanto, é equivalente a OrderBy(b).ThenBy(a).
Jon Skeet
2
Achei essa distinção irritante ao tentar criar consultas de maneira genérica, então ajudei um pouco a produzir OrderBy / ThenBy na ordem correta, para quantos tipos você quiser.
Há várias maneiras de você usar isso dependendo do seu caso de uso, mas se, por exemplo, você passar uma lista de colunas e direções de classificação como strings e bools, poderá fazer um loop sobre elas e usá-las em uma opção como:
OrderBy(a).OrderBy(b).OrderBy(c)
ainda usa a saída da classificação anterior e reordena a coisa toda, mas preserva a ordem existente (da etapa anterior) em que dois elementos são iguais na nova comparação. Imagine que apenas temosOrderBy(a).OrderBy(b)
. Os resultados deOrderBy(a)
estão ema
ordem crescente e, em seguida, são reordenados de acordo comb
. No resultado final, se dois valores tiverem o mesmob
valor, eles serão ordenadosa
devido à classificação ser estável - portanto, é equivalente aOrderBy(b).ThenBy(a)
.Achei essa distinção irritante ao tentar criar consultas de maneira genérica, então ajudei um pouco a produzir OrderBy / ThenBy na ordem correta, para quantos tipos você quiser.
Há várias maneiras de você usar isso dependendo do seu caso de uso, mas se, por exemplo, você passar uma lista de colunas e direções de classificação como strings e bools, poderá fazer um loop sobre elas e usá-las em uma opção como:
O resultado em
sortedQuery
é classificado na ordem desejada, em vez de recorrer repetidamente, como a outra resposta aqui alerta.fonte
se você quiser classificar mais de um campo, vá para ThenBy:
como isso
fonte
Sim, você nunca deve usar múltiplos OrderBy se estiver tocando com várias teclas. ThenBy é uma aposta mais segura, pois será executada após OrderBy.
fonte