.ToLookup<TSource, TKey>
zwraca plik ILookup<TKey, TSource>
. ILookup<TKey, TSource>
implementuje również interfejs IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
zwraca plik IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup ma przydatną właściwość indeksatora, więc może być używana w sposób podobny do słownika (lub podobny do wyszukiwania), podczas gdy GroupBy nie może. GroupBy bez indeksatora to uciążliwa praca; właściwie jedynym sposobem, w jaki możesz odwołać się do zwracanego obiektu, jest przejście przez niego (lub użycie innej metody rozszerzenia LINQ). Innymi słowy, w każdym przypadku, gdy działa GroupBy, ToLookup również będzie działać.
Wszystko to pozostawia mi pytanie, dlaczego miałbym kiedykolwiek zawracać sobie głowę GroupBy? Dlaczego miałoby istnieć?
GroupBy
JestIQuerable
,ILookup
nie jestLookup
, aleGroupBy
tworzy je, gdy wynik jest wyliczany referencjeource.microsoft.com/#System.Core/System/Linq/…Odpowiedzi:
Co się dzieje, gdy wywołujesz ToLookup na obiekcie reprezentującym zdalną tabelę bazy danych z miliardem wierszy?
Miliard wierszy jest przesyłanych przez sieć, a Ty lokalnie tworzysz tabelę przeglądową.
Co się dzieje, gdy wywołujesz GroupBy na takim obiekcie?
Budowany jest obiekt zapytania; Koniec opowieści.
Po wyliczeniu tego obiektu zapytania analiza tabeli jest wykonywana na serwerze bazy danych, a zgrupowane wyniki są odsyłane na żądanie po kilka na raz.
Logicznie rzecz biorąc, to to samo, ale implikacje wydajnościowe każdego z nich są zupełnie inne. Wywołanie ToLookup oznacza, że chcę teraz mieć pamięć podręczną całej rzeczy zorganizowaną według grup . Wywołanie GroupBy oznacza „Buduję obiekt, który ma odpowiadać pytaniu 'jak te rzeczy wyglądałyby, gdybym je uporządkował według grup?'”
źródło
IQueryable<T>
przedstawienie. Twoja odpowiedź obejmuje tę sytuację, ale kiedy jest po prostu olIEnumerable<T>
(LINQ-to-Objects), może się wydawać, że nie ma powodu, aby używać jednego nad drugim, do czego, jak sądzę, próbuje dotrzeć @Shlomo. Nie jest toIQueryable<T>
przypadek, ale przypadek LINQ-to-Objects.W prostych słowach świata LINQ:
ToLookup()
- natychmiastowa realizacjaGroupBy()
- wykonanie odroczoneźródło
Oba są podobne, ale są używane w różnych scenariuszach.
.ToLookup()
zwraca gotowy do użycia obiekt, który ma już wszystkie grupy (ale nie zawartość grupy), które zostały chętnie załadowane. Z drugiej strony,.GroupBy()
zwraca leniwie ładowaną sekwencję grup.Różni dostawcy LINQ mogą mieć różne zachowania dla chętnego i leniwego ładowania grup. W przypadku LINQ-to-Object prawdopodobnie robi to niewielką różnicę, ale w przypadku LINQ-to-SQL (lub LINQ-to-EF itp.) Operacja grupowania jest wykonywana na serwerze bazy danych, a nie na kliencie, więc możesz chcieć wykonać dodatkowe filtrowanie na kluczu grupy (który generuje
HAVING
klauzulę), a następnie pobrać tylko niektóre grupy zamiast wszystkich..ToLookup()
nie pozwoliłby na taką semantykę, ponieważ wszystkie elementy są chętnie grupowane.źródło