.ToLookup<TSource, TKey>
renvoie un ILookup<TKey, TSource>
. ILookup<TKey, TSource>
implémente également l'interface IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
renvoie un IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup a la propriété d'indexation pratique, donc il peut être utilisé d'une manière de type dictionnaire (ou de recherche), contrairement à GroupBy. GroupBy sans l'indexeur est difficile à utiliser; à peu près le seul moyen de référencer l'objet de retour est de le parcourir en boucle (ou d'utiliser une autre méthode d'extension LINQ). En d'autres termes, dans tous les cas où GroupBy fonctionne, ToLookup fonctionnera également.
Tout cela me laisse avec la question pourquoi devrais-je jamais m'embêter avec GroupBy? Pourquoi devrait-il exister?
GroupBy
EstIQuerable
,ILookup
n'est pasLookup
, mais leGroupBy
crée lorsque le résultat est énuméré referencesource.microsoft.com/#System.Core/System/Linq/...Réponses:
Que se passe-t-il lorsque vous appelez ToLookup sur un objet représentant une table de base de données distante contenant un milliard de lignes?
Le milliard de lignes est envoyé sur le fil et vous créez la table de recherche localement.
Que se passe-t-il lorsque vous appelez GroupBy sur un tel objet?
Un objet de requête est construit; fin de l'histoire.
Lorsque cet objet de requête est énuméré, l'analyse de la table est effectuée sur le serveur de base de données et les résultats groupés sont renvoyés à la demande quelques uns à la fois.
Il s'agit logiquement de la même chose, mais les implications de chacun sur les performances sont complètement différentes. Appeler ToLookup signifie que je veux un cache de la chose entière maintenant organisé par groupe . Appeler GroupBy signifie "Je construis un objet pour représenter la question" à quoi ressembleraient ces choses si je les organisais par groupe? ""
la source
IQueryable<T>
représentation. Votre réponse couvre cette situation, mais quand c'est tout simplement olIEnumerable<T>
(LINQ-to-Objects), il peut sembler qu'il n'y a pas de raison d'utiliser l'un par rapport à l'autre, ce que je crois que @Shlomo essaie de faire. Pas leIQueryable<T>
cas, mais le cas LINQ-to-Objects.En termes simples du monde LINQ:
ToLookup()
- exécution immédiateGroupBy()
- exécution différéela source
Les deux sont similaires, mais sont utilisés dans des scénarios différents.
.ToLookup()
renvoie un objet prêt à l'emploi qui a déjà tous les groupes (mais pas le contenu du groupe) chargés avec impatience. D'autre part,.GroupBy()
renvoie une séquence de groupes chargée différemment.Différents fournisseurs LINQ peuvent avoir des comportements différents pour le chargement hâtif et paresseux des groupes. Avec LINQ-to-Object, cela fait probablement peu de différence, mais avec LINQ-to-SQL (ou LINQ-to-EF, etc.), l'opération de regroupement est effectuée sur le serveur de base de données plutôt que sur le client, et vous voudrez peut-être pour effectuer un filtrage supplémentaire sur la clé de groupe (qui génère une
HAVING
clause) et n'obtenir que certains des groupes au lieu de tous..ToLookup()
ne permettrait pas une telle sémantique puisque tous les éléments sont regroupés avec empressement.la source