Notez comment vous pouvez utiliser le même nom à chaque fois. Cela équivaut également à:
tmp =from o in invoices.InvoiceCollectionorderby o.InvoiceOwner.LastName,
o.InvoiceOwner.FirstName,
o.InvoiceIDselect o;
Si vous appelez OrderByplusieurs fois, cela réorganisera complètement la séquence trois fois ... donc l'appel final sera effectivement l'appel dominant. Vous pouvez (dans LINQ to Objects) écrire
foo.OrderBy(x).OrderBy(y).OrderBy(z)
ce qui équivaudrait à
foo.OrderBy(z).ThenBy(y).ThenBy(x)
car l'ordre de tri est stable, mais vous ne devriez absolument pas:
C'est difficile à lire
Il ne fonctionne pas bien (car il réorganise toute la séquence)
Cela peut ne pas fonctionner avec d'autres fournisseurs (par exemple LINQ to SQL)
Ce n'est essentiellement pas la façon dont il a OrderByété conçu pour être utilisé.
Le but de OrderByest de fournir la projection d'ordre "la plus importante"; puis utilisez ThenBy(à plusieurs reprises) pour spécifier des projections d'ordre secondaire, tertiaire, etc.
En fait, pensez-y de cette façon: OrderBy(...).ThenBy(...).ThenBy(...)vous permet de créer une seule comparaison composite pour deux objets, puis de trier la séquence une fois en utilisant cette comparaison composite. C'est presque certainement ce que vous voulez.
C'est ce que je pensais mais, pour une raison quelconque, OrderBy, ThenBy, ThenBy ne semble pas trier correctement, alors je me suis demandé si je l'utilisais correctement.
DazManCat
14
Notez que dans la syntaxe de la requête, le mot-clé de classement est en fait orderby et non trié. ( désolé pour le pédantisme - je voulais juste dire que j'ai une fois corrigé un message de Jon Skeet )
fostandy
1
Jon, quelque chose ne me convient pas dans la section mais vous ne devriez absolument pas (qui concerne l'application de plusieurs commandes en utilisant la syntaxe linq fluent car elle se traduit par ThenBy, dans les requêtes locales): Cela ne fonctionne pas bien (car il réorganise toute la séquence) - voulez-vous dire le 2ème ou le 3ème ordre en réorganisant toute la séquence? si tel est le cas, comment cela se traduira-t-il encore en ThenBy après avoir réordonné la séquence en supprimant l'ordre précédent?
Veverke
@Veverke: Il réorganise toute la séquence, mais de manière stable, donc si deux valeurs ont la même valeur z, l'ordre dépendra de y puis de x.
Jon Skeet
1
@Veverke: OrderBy(a).OrderBy(b).OrderBy(c)utilise toujours la sortie du tri précédent, et réorganise le tout, mais il conserve l'ordre existant (de l'étape précédente) où deux éléments sont égaux sous la nouvelle comparaison. Imaginez que nous avons juste OrderBy(a).OrderBy(b). Les résultats de OrderBy(a)sont classés par aordre croissant , puis ils sont réorganisés en fonction de b. Dans le résultat final, si deux valeurs ont la même bvaleur, elles seront classées par acar le tri est stable - c'est donc équivalent à OrderBy(b).ThenBy(a).
Jon Skeet
2
J'ai trouvé cette distinction ennuyeuse en essayant de créer des requêtes de manière générique, j'ai donc fait une petite aide pour produire OrderBy / ThenBy dans le bon ordre, pour autant de types que vous le souhaitez.
Il existe de nombreuses façons d'utiliser cela en fonction de votre cas d'utilisation, mais si vous deviez, par exemple, passer une liste de colonnes de tri et de directions sous forme de chaînes et de booléens, vous pourriez les parcourir en boucle et les utiliser dans un commutateur comme:
Oui, vous ne devez jamais utiliser plusieurs OrderBy si vous jouez avec plusieurs touches. ThenBy est un pari plus sûr car il fonctionnera après OrderBy.
OrderBy(a).OrderBy(b).OrderBy(c)
utilise toujours la sortie du tri précédent, et réorganise le tout, mais il conserve l'ordre existant (de l'étape précédente) où deux éléments sont égaux sous la nouvelle comparaison. Imaginez que nous avons justeOrderBy(a).OrderBy(b)
. Les résultats deOrderBy(a)
sont classés para
ordre croissant , puis ils sont réorganisés en fonction deb
. Dans le résultat final, si deux valeurs ont la mêmeb
valeur, elles seront classées para
car le tri est stable - c'est donc équivalent àOrderBy(b).ThenBy(a)
.J'ai trouvé cette distinction ennuyeuse en essayant de créer des requêtes de manière générique, j'ai donc fait une petite aide pour produire OrderBy / ThenBy dans le bon ordre, pour autant de types que vous le souhaitez.
Il existe de nombreuses façons d'utiliser cela en fonction de votre cas d'utilisation, mais si vous deviez, par exemple, passer une liste de colonnes de tri et de directions sous forme de chaînes et de booléens, vous pourriez les parcourir en boucle et les utiliser dans un commutateur comme:
Le résultat
sortedQuery
est trié dans l'ordre souhaité, au lieu de recourir à plusieurs reprises, comme l'autre réponse le met en garde.la source
si vous souhaitez trier plus d'un champ, choisissez ThenBy:
comme ça
la source
Oui, vous ne devez jamais utiliser plusieurs OrderBy si vous jouez avec plusieurs touches. ThenBy est un pari plus sûr car il fonctionnera après OrderBy.
la source