.ToLookup<TSource, TKey>
gibt ein zurück ILookup<TKey, TSource>
. ILookup<TKey, TSource>
implementiert auch Schnittstelle IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
gibt ein zurück IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup verfügt über die praktische Indexer-Eigenschaft, sodass es wie ein Wörterbuch (oder ein Lookup) verwendet werden kann, GroupBy jedoch nicht. GroupBy ohne Indexer ist ein Problem. Die einzige Möglichkeit, auf das Rückgabeobjekt zu verweisen, besteht darin, es zu durchlaufen (oder eine andere LINQ-Erweiterungsmethode zu verwenden). Mit anderen Worten, in jedem Fall, in dem GroupBy funktioniert, funktioniert ToLookup auch.
All dies lässt mich die Frage offen, warum ich mich jemals mit GroupBy beschäftigen sollte. Warum sollte es existieren?
GroupBy
IstIQuerable
,ILookup
ist nichtLookup
, aber es wirdGroupBy
erstellt, wenn das Ergebnis aufgelistet ist. referencesource.microsoft.com/#System.Core/System/Linq/…Antworten:
Was passiert, wenn Sie ToLookup für ein Objekt aufrufen, das eine entfernte Datenbanktabelle mit einer Milliarde Zeilen darstellt?
Die Milliarden Zeilen werden über die Leitung gesendet, und Sie erstellen die Nachschlagetabelle lokal.
Was passiert, wenn Sie GroupBy für ein solches Objekt aufrufen?
Ein Abfrageobjekt wird erstellt. Ende der Geschichte.
Wenn dieses Abfrageobjekt aufgelistet ist, wird die Analyse der Tabelle auf dem Datenbankserver durchgeführt und die gruppierten Ergebnisse werden bei Bedarf nacheinander zurückgesendet .
Logischerweise sind sie dasselbe, aber die Auswirkungen auf die Leistung sind völlig unterschiedlich. Wenn ich ToLookup aufrufe, möchte ich einen Cache der gesamten Sache, der gerade nach Gruppen organisiert ist . Das Aufrufen von GroupBy bedeutet "Ich baue ein Objekt, um die Frage darzustellen, wie diese Dinge aussehen würden, wenn ich sie nach Gruppen organisieren würde."
quelle
IQueryable<T>
Darstellung ab. Ihre Antwort deckt diese Situation ab, aber wenn es einfach nur alt istIEnumerable<T>
(LINQ-to-Objects), kann es so aussehen, als gäbe es keinen Grund, einen über den anderen zu verwenden. Ich glaube, @Shlomo versucht, dies zu erreichen. Nicht derIQueryable<T>
Fall, sondern der Fall LINQ-to-Objects.In einfachen Worten der LINQ-Welt:
ToLookup()
- sofortige AusführungGroupBy()
- Aufgeschobene Ausführungquelle
Die beiden sind ähnlich, werden jedoch in unterschiedlichen Szenarien verwendet.
.ToLookup()
Gibt ein gebrauchsfertiges Objekt zurück, in dem bereits alle Gruppen (aber nicht der Inhalt der Gruppe) eifrig geladen sind. Gibt andererseits.GroupBy()
eine verzögert geladene Folge von Gruppen zurück.Verschiedene LINQ-Anbieter können unterschiedliche Verhaltensweisen für das eifrige und verzögerte Laden der Gruppen aufweisen. Mit LINQ-to-Object macht es wahrscheinlich wenig Unterschied, aber mit LINQ-to-SQL (oder LINQ-to-EF usw.) wird der Gruppierungsvorgang eher auf dem Datenbankserver als auf dem Client ausgeführt eine zusätzliche Filterung für den Gruppenschlüssel durchführen (der eine
HAVING
Klausel generiert ) und dann nur einige der Gruppen anstelle aller abrufen..ToLookup()
würde eine solche Semantik nicht zulassen, da alle Elemente eifrig gruppiert sind.quelle