Zwróć uwagę, jak za każdym razem możesz używać tej samej nazwy. Jest to również równoważne z:
tmp =from o in invoices.InvoiceCollectionorderby o.InvoiceOwner.LastName,
o.InvoiceOwner.FirstName,
o.InvoiceIDselect o;
Jeśli sprawdzisz OrderBywiele razy, skutecznie zmieni to kolejność całkowicie trzy razy ... więc ostateczne wezwanie będzie w rzeczywistości dominującym. Państwo może (w LINQ to Objects) zapisu
foo.OrderBy(x).OrderBy(y).OrderBy(z)
co byłoby równoważne z
foo.OrderBy(z).ThenBy(y).ThenBy(x)
ponieważ porządek sortowania jest stabilny, ale absolutnie nie powinieneś:
Trudno to czytać
Nie działa dobrze (ponieważ zmienia kolejność całej sekwencji)
Może nie działać w innych dostawcach (np. LINQ to SQL)
W zasadzie nie jest to sposób, w jaki OrderByzostał zaprojektowany do użytku.
Chodzi o OrderBydostarczenie „najważniejszej” projekcji porządkującej; następnie użyj ThenBy(wielokrotnie), aby określić projekcje zamawiania drugorzędnych, trzeciorzędnych itp.
Pomyśl o tym w ten sposób: OrderBy(...).ThenBy(...).ThenBy(...)pozwala zbudować pojedyncze porównanie złożone dla dowolnych dwóch obiektów, a następnie posortować sekwencję raz, używając tego porównania złożonego. Prawie na pewno tego chcesz.
Tak myślałem, ale z jakiegoś powodu OrderBy, ThenBy, ThenBy nie wydaje się sortować poprawnie, więc zastanawiałem się, czy używam go poprawnie.
DazManCat
14
Zauważ, że w składni zapytania słowem kluczowym służącym do porządkowania jest w rzeczywistości sortowanie, a nie sortowanie według. ( przepraszam za pedanterię - chciałem tylko powiedzieć, że kiedyś poprawiłem post Jona Skeeta )
fostandy.
1
Jon, coś nie pasuje do mnie z sekcji, ale absolutnie nie powinieneś jej używać (dotyczy to stosowania wielu porządków przy użyciu płynnej składni linq, ponieważ w zapytaniach lokalnych przekłada się na ThenBy): Nie działa dobrze (ponieważ zmienia kolejność całej sekwencji) - czy masz na myśli drugie lub trzecie zamówienie, zmieniając kolejność całej sekwencji? jeśli tak, w jaki sposób będzie to nadal przekładać się na ThenBy po ponownym uporządkowaniu sekwencji, odrzucając poprzednią kolejność?
Veverke,
@Veverke: Zmienia kolejność całej sekwencji, ale w stabilny sposób, więc jeśli dwie wartości mają tę samą wartość z, kolejność będzie zależeć od y, a następnie od x.
Jon Skeet,
1
@Veverke: OrderBy(a).OrderBy(b).OrderBy(c)nadal używa wyjścia poprzedniego rodzaju i zmienia kolejność całości, ale zachowuje istniejącą kolejność (z poprzedniego kroku), w której dwa elementy są równe w nowym porównaniu. Wyobraź sobie, że właśnie to zrobiliśmy OrderBy(a).OrderBy(b). Wyniki OrderBy(a)są w akolejności rosnącej , a następnie są one uporządkowane zgodnie z b. W ostatecznym wyniku, jeśli dwie wartości mają tę samą bwartość, zostaną uporządkowane według, aponieważ sortowanie jest stabilne - więc jest równoważne OrderBy(b).ThenBy(a).
Jon Skeet
2
To rozróżnienie było dla mnie irytujące, próbując budować zapytania w sposób ogólny, więc zrobiłem mały pomocnik, aby utworzyć OrderBy / ThenBy we właściwej kolejności, dla dowolnej liczby rodzajów.
Istnieje wiele sposobów, w jakie możesz tego użyć, w zależności od przypadku użycia, ale jeśli na przykład przekazałeś listę kolumn sortowania i kierunków jako łańcuchy i wartości logiczne, możesz je zapętlić i użyć w przełączniku, takim jak:
Tak, nigdy nie powinieneś używać wielu OrderBy, jeśli grasz z wieloma klawiszami. ThenBy jest bezpieczniejszym zakładem, ponieważ będzie działać po OrderBy.
OrderBy(a).OrderBy(b).OrderBy(c)
nadal używa wyjścia poprzedniego rodzaju i zmienia kolejność całości, ale zachowuje istniejącą kolejność (z poprzedniego kroku), w której dwa elementy są równe w nowym porównaniu. Wyobraź sobie, że właśnie to zrobiliśmyOrderBy(a).OrderBy(b)
. WynikiOrderBy(a)
są wa
kolejności rosnącej , a następnie są one uporządkowane zgodnie zb
. W ostatecznym wyniku, jeśli dwie wartości mają tę samąb
wartość, zostaną uporządkowane według,a
ponieważ sortowanie jest stabilne - więc jest równoważneOrderBy(b).ThenBy(a)
.To rozróżnienie było dla mnie irytujące, próbując budować zapytania w sposób ogólny, więc zrobiłem mały pomocnik, aby utworzyć OrderBy / ThenBy we właściwej kolejności, dla dowolnej liczby rodzajów.
Istnieje wiele sposobów, w jakie możesz tego użyć, w zależności od przypadku użycia, ale jeśli na przykład przekazałeś listę kolumn sortowania i kierunków jako łańcuchy i wartości logiczne, możesz je zapętlić i użyć w przełączniku, takim jak:
Wynik
sortedQuery
jest sortowany w żądanej kolejności, zamiast ciągłego uciekania się, jak ostrzega druga odpowiedź.źródło
jeśli chcesz posortować więcej niż jedno pole, przejdź do ThenBy:
lubię to
źródło
Tak, nigdy nie powinieneś używać wielu OrderBy, jeśli grasz z wieloma klawiszami. ThenBy jest bezpieczniejszym zakładem, ponieważ będzie działać po OrderBy.
źródło