7
votes

Différences lors de l'utilisation iEnumerable et iquérissable comme un type d'objet

Comme je le comprends lorsque j'utilise des méthodes d'extension LINQ (avec la syntaxe d'expression Lambda) sur iquérirable dans la base de ObjectSet Ils sont traduits en linq sur SQL requêtes. Ce que je veux dire, c'est que la commande xxx

est exactement la même que xxx

donc non d'entre eux frappe la base de données jusqu'à ce qu'ils utilisateurs32yearSold < / code> sont énumérées pour le cycle ou tel. (J'espère que je comprends bien cela correctement).

Mais ce qui va se passer si je ne masque pas ce ObjectSet comme iquérirable mais comme IEnumerable ? Donc, si le type de celui-ci est ienumerable ? xxx

est-ce que cela va frapper la base de données immédiatement (si oui alors? À droite sur la première ligne ou sur la seconde)? Ou allez-t-il se comporter comme la commande précédente qui ne s'appliquera pas de base de données avant que users32yearSold est énumérée? Y aura-t-il une différence si j'utilise suivant à la place? xxx

merci


0 commentaires

4 Réponses :


0
votes

Vous êtes correct à propos de IQueryable. Quant à iEnumerable, cela frapperait la base de données immédiatement lors de l'attribution d'un utilisateur iEnumerable.

Il n'y a pas de différence réelle entre l'utilisation de LINQ Extensions par rapport à la syntaxe dans l'exemple que vous avez fourni. Parfois, l'un ou l'autre sera plus pratique (voir LINQ-Extension-Méthodes-vs-linq -syntax ), mais imo c'est plus sur la préférence personnelle.


1 commentaires

Donc, lorsque iEnumerable est utilisé, il frappera immédiatement la base de données et il demandera toutes les lignes de la table des utilisateurs ou simplement celles qui ont l'âge réglé sur 32?



6
votes

Voici une explication simple: xxx

si vous utilisez userenumerable , lorsque vous commencez à énumérer dessus, les deux S être exécuté en séquence; D'abord, le ObjectSet va chercher tous les objets et les objets seront filtrés à ceux de ceux de l'âge de 32 ans, puis ceux-ci seront filtrés à ceux dont le nom commence par g.

si vous utilisez usersQUeryAsable , les deux s renvoient de nouveaux objets qui accumuleront les critères de sélection et lorsque vous commencez à énumérer dessus, il traduira tous les critères à un requete. Cela fait une différence notable.

Normalement, vous n'avez pas besoin de vous inquiéter, car vous direz que vous disez soit des utilisateurs var ou Utilisateurs lorsque vous Déclarez votre variable, ce qui signifie que c # saura que vous souhaitez appeler la méthode la plus spécifique disponible sur ObjectSet et les méthodes d'opérateur IQuyer Opérateur de requête (, Sélectionnez , ...) sont plus spécifiques que les méthodes iEnumerables . Cependant, si vous transmettez des objets sur des méthodes qui prennent des paramètres iEnumerables , ils peuvent finir par appeler les mauvaises méthodes.

Vous pouvez également utiliser la façon dont cela fonctionne à votre avantage en utilisant Le asenumerable () et asquérissable () méthodes pour commencer à utiliser l'autre approche. Par exemple, var groupedpeople = users.aves (user => user.age> 15) .asenumerable (). Groupby (utilisateur => utilisateur.age); extraire les bons utilisateurs avec une base de données Requête puis regroupez les objets localement.

Comme d'autres ont dit, il convient de répéter que rien ne se passe jusqu'à ce que vous commenciez à énumérer les séquences (avec foreach ). Vous devriez maintenant comprendre pourquoi il ne pouvait pas être autre chose: si tous les résultats ont été récupérés à la fois, vous ne pouvez pas construire des requêtes à traduire dans une requête plus efficace (comme une requête SQL).


0 commentaires

12
votes

supprime ma réponse parce que je viens de le tester et que cela fonctionne exactement comme je l'ai décrit:

Aucune des requêtes mentionnées ne touchera la base de données car il n'y avait pas d'énumération. La différence entre iquérirable requête et iEnumerable est que dans le cas de iquéryable le filtrage sera exécuté sur le serveur de base de données alors que dans le cas de IEnumerable Tous les objets seront chargés à partir de la base de données à une mémoire et le filtrage sera effectué en code .NET (Linq-to-Objects). Comme vous pouvez l'imaginer, c'est généralement un tueur de performance.

J'ai écrit un test simple dans mon projet: xxx


5 commentaires

"Aucune des requêtes mentionnées ne frappera la base de données car il n'y avait pas de dénombrement" n'est pas contradictoire aux 2 réponses précédentes. J'ai vraiment de bonnes réponses de toi jusqu'à présent, alors je tente de prendre vos réponses plus au sérieux. Toujours vraiment "il n'y avait pas d'énumération"? IEnumerable n'a pas d'énumération lorsque où (u => u.age == 32) est appelé dessus? Comment est-ce que cela (je peux imaginer que cela fonctionne de la même manière que iquéryable mais savoir savoir mieux alors deviner)?


Je l'ai testé et je la répandre de ma réponse parce que après l'avoir vérifié dans SQL Profiler, je vois que ma réponse était correcte.


Comme je l'ai dit, je l'ai pris sérieusement pour la première fois ... alors quand j'appelle où (u => u.age == 32) sur certains ienumerable il n'est pas Aller à énumérer mais il suffit de créer de nouveaux énumérables qui se référent à l'original et à un filtre "où" attaché? Ou comment ça marche? Peut-être que cela devrait être une autre question ...


Je ne suis pas capable de répondre à la manière dont cela fonctionne, mais cela a du sens pour moi ( iEnumerable et iquéryable ont une exécution deFered). C'était la raison pour laquelle j'ai douté de ma réponse avant de le tester.


Comme je le comprends, quand un appel d'un autre () ou d'un autre appel LINQ est effectué sur une variable iquéry , un arbre d'objets représentant les expressions est ajouté à l'objet implémentant iquéryable . IQueryable Implements iEnumerable , donc la même chose se passe. Lorsque vous énumérez réellement l'expression, l'arborescence d'expression est évaluée / convertie en SQL et transmise au serveur de base de données.



1
votes

La différence est que iEnumerable effectue les filtres si elles sont plus, une à la fois. Par exemple, à partir de 100 éléments produira 20 par le premier filtre, puis filtrera la deuxième fois le 10. Il effectuera une requête à la base de données, mais téléchargera des données inutiles. Utiliser IQueryable téléchargera à nouveau avec une requête, mais uniquement les 10 éléments requis. Le lien suivant donne d'excellents exemples de la façon dont ces requêtes fonctionnent: https: //FilteredCode.WordPress .COM / 2016/04/29 / iEnumérable-vs-iquérir-2-QUESTION-QUESTIONS /


0 commentaires