Quelle est la différence entre IQueryable et IEnumerable?

Quelle est la différence entre IQueryable<T> et IEnumerable<T> ?


Voir aussi Quelle est la différence entre IQueryable et IEnumerable qui chevauche cette question.

386
demandé sur Community 2008-10-31 10:18:42

12 réponses

tout D'abord, IQueryable<T> étend l'interface IEnumerable<T> , donc tout ce que vous pouvez faire avec un "plain" IEnumerable<T> , vous pouvez aussi faire avec un IQueryable<T> .

IEnumerable<T> vient d'avoir une méthode GetEnumerator() qui retourne une méthode Enumerator<T> pour laquelle vous pouvez appeler sa méthode MoveNext() pour itérer à travers une séquence de T .

Ce IQueryable<T> a que IEnumerable<T> n'est pas sont deux propriétés en particulier-l'une qui pointe vers un fournisseur de requête (par exemple, un LINQ à fournisseur SQL) et une autre pointant vers une syntaxe expression de requête représentant l'objet IQueryable<T> comme un exécutable arbre abstrait qui peut être compris par le fournisseur de requête donné (pour la plupart, vous ne pouvez pas donner une expression LINQ to SQL à un fournisseur LINQ to Entities sans un exception levée).

l'expression peut simplement être une expression constante de l'objet lui-même ou un arbre plus complexe d'un ensemble composé d'opérateurs de requête et d'opérandes. Les méthodes IQueryProvider.Execute() ou IQueryProvider.CreateQuery() du fournisseur de requête sont appelées avec une Expression qui lui est transmise, et ensuite soit un résultat de requête soit un autre IQueryable est retourné, respectivement.

236
répondu Mark Cidade 2017-03-30 13:26:04

la principale différence est que les opérateurs LINQ pour IQueryable<T> prennent Expression objets au lieu de délégués, ce qui signifie la logique de requête personnalisée qu'il reçoit, par exemple, un prédicat ou un sélecteur de valeur, est sous la forme d'un arbre d'expression au lieu d'un délégué à une méthode.

  • IEnumerable<T> est idéal pour travailler avec des séquences qui sont itérées en mémoire, mais
  • IQueryable<T> permet des choses hors de la mémoire comme un source de données distante, comme une base de données ou un service web.

exécution de la Requête:

  • lorsque l'exécution d'une requête doit être effectuée "en cours de traitement" , typiquement tout ce qui est requis est le code (en tant que code) pour exécuter chaque partie de la requête.

  • où l'exécution sera effectuée out-of-process , la logique de la requête doit être représentée dans les données de sorte que le fournisseur de LINQ puisse la convertir dans la forme appropriée pour l'exécution hors de la mémoire-que ce soit une requête LDAP, SQL ou autre.

plus de:

http://www.codeproject.com/KB/cs/646361/WhatHowWhere.jpg

180
répondu VonC 2017-05-23 11:55:10

il s'agit d'une belle vidéo sur ma page Facebook qui démontre comment ces interfaces diffèrent , mérite une montre.

ci-dessous va une longue réponse descriptive pour elle.

le premier point important à retenir est IQueryable l'interface hérite de IEnumerable , donc tout ce que IEnumerable peut faire, IQueryable peut aussi le faire.

enter image description here

Il y a beaucoup de différences, mais discutons de la grande différence qui fait la plus grande différence. IEnumerable l'interface est utile lorsque votre collection est chargée en utilisant LINQ ou le cadre D'entité et vous voulez appliquer un filtre sur la collection.

considérons le code simple ci-dessous qui utilise IEnumerable avec le cadre d'entité. Il utilise un filtre Where pour obtenir des enregistrements dont le EmpId est 2 .

EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees; 
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();

cette où le filtre est exécuté du côté du client où le code IEnumerable est. En d'autres termes, toutes les données sont récupérées à partir de la base de données et puis au client ses balayages et obtient l'enregistrement avec EmpId est 2 .

enter image description here

mais maintenant Voir le code ci-dessous nous avons changé IEnumerable à IQueryable . Il crée une requête SQL du côté du serveur et seules les données nécessaires sont envoyées du côté du client.

EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp =  emp.Where(x => x.Empid == 2).ToList<Employee>();

enter image description here

ainsi la différence entre IQueryable et IEnumerable concerne l'endroit où la logique du filtre est exécutée. On exécute côté client et l'autre s'exécute sur la base de données.

donc si vous travaillez avec seulement la collecte de données en mémoire IEnumerable est un bon choix, mais si vous voulez pour la collecte de données d'interrogation qui est connecté avec la base de données " IQueryable est un meilleur choix car il réduit le trafic réseau et utilise la puissance du langage SQL.

155
répondu Shivprasad Koirala 2016-11-25 21:08:24

IEnumerable: IEnumerable est le mieux adapté pour travailler avec la collection en mémoire (ou des requêtes locales). IEnumerable ne se déplace pas entre les articles, il est en avant seulement collection.

IQueryable: IQueryable convient le mieux pour la source de données à distance, comme une base de données ou un service web (ou des requêtes à distance). IQueryable est une fonctionnalité très puissante qui permet une variété de scénarios intéressants d'exécution différée (comme le questions basées sur la composition).

donc quand vous devez simplement itérer à travers la collection en mémoire, utilisez IEnumerable, si vous avez besoin de faire toute manipulation avec la collection comme ensemble de données et d'autres sources de données, utilisez IQueryable

51
répondu Talha 2013-07-14 14:40:17

Dans des mots simples à l'autre différence majeure est que IEnumerable exécuter une requête select sur le côté serveur, la charge en mémoire des données côté client et ensuite filtrer les données tout en IQueryable exécuter une requête select sur le côté serveur avec tous les filtres.

16
répondu A.T. 2013-05-16 08:59:08

dans la vraie vie, si vous utilisez un ORM comme LINQ-to-SQL

  • si vous créez un IQueryable, alors la requête peut être convertie en sql et exécutée sur le serveur de base de données
  • si vous créez un IEnumerable, alors toutes les lignes seront tirées dans la mémoire comme des objets avant d'exécuter la requête.

dans les deux cas si vous n'appelez pas un ToList() ou ToArray() alors la requête sera exécutée chaque fois qu'elle est utilisée, donc, dire, vous avez un IQueryable<T> et vous remplissez 4 zones de liste, alors la requête sera exécutée sur la base de données 4 fois.

aussi si vous extendez votre requête:

q.Where(x.name = "a").ToList()

puis avec un IQueryable le SQL généré contiendra "where name = "a", mais avec un IEnumerable beaucoup plus de rôles seront retirés de la base de données, puis le X. name = " a " check will be done by .NET.

16
répondu Ian Ringrose 2015-11-27 15:10:36

IEnumerable fait référence à une collection mais IQueryable n'est qu'une requête et elle sera générée à l'intérieur d'un arbre D'expressions.nous allons exécuter cette requête pour obtenir des données de la base de données.

9
répondu seyed 2012-11-14 22:14:59

ci-dessous mentionné petit test pourrait vous aider à comprendre un aspect de la différence entre IQueryable<T> et IEnumerable<T> . J'ai reproduit cette réponse de ce poste où j'essayais d'ajouter des corrections à quelqu'un d'autre poste

j'ai créé la structure suivante dans DB (script DDL):

CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)

voici le script d'insertion de l'enregistrement (script DML):

INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO

maintenant, mon but était de simplement obtenir les 2 premiers enregistrements de la table Employee dans la base de données. J'ai ajouté un ADO.NET élément de modèle de données D'entité dans mon application de console pointant vers la table Employee dans ma base de données et commencé à écrire des requêtes LINQ.

Code pour la route IQueryable :

using (var efContext = new EfTestEntities())
{
    IQueryable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

quand j'ai commencé à exécuter ce programme, j'avais aussi commencé une session de SQL Query profiler sur L'instance de mon serveur SQL et voici le résumé de exécution:

  1. nombre Total de requêtes envoyées: 1
  2. le texte de la Requête: SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]

c'est juste que IQueryable est assez intelligent pour appliquer la clause Top (2) du côté du serveur de base de données lui-même de sorte qu'il apporte seulement 2 sur 5 enregistrements sur le fil. Aucun autre filtrage en mémoire n'est requis du côté de l'ordinateur client.

Code de route IEnumerable :

using (var efContext = new EfTestEntities())
{
    IEnumerable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

résumé de l'exécution dans cette affaire:

  1. nombre Total de requêtes envoyées: 1
  2. texte de requête capturé dans le profileur SQL: SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]

maintenant la chose est IEnumerable a apporté tous les 5 enregistrements présents dans Salary table et a ensuite effectué un filtrage en mémoire sur l'ordinateur client pour obtenir les 2 premiers enregistrements. Donc plus de données (3 supplémentaires dossiers dans ce cas) ont été transférés sans raison valable.

7
répondu RBT 2017-07-17 06:57:44

Voici ce que j'ai écrit sur un poste similaire (sur ce sujet). (Et non, je n'ai pas l'habitude de citer moi-même, mais ce sont de très bons articles.)

"cet article est utile: IQueryable vs IEnumerable in LINQ-to-SQL .

citant cet article, " selon la documentation MSDN, les appels faits sur IQueryable fonctionnent en construisant l'arbre d'expression interne à la place. "Ces méthodes qui étendent IQueryable (Of T) n'effectuent aucune interrogeant directement. Au lieu de cela, leur fonctionnalité est de construire un objet D'Expression, qui est un arbre d'expression qui représente la requête cumulative. "'

les arbres D'Expression sont une construction très importante en C# et sur la plateforme .NET. (Ils sont importants en général, mais C# rend très utile.) Pour mieux comprendre la différence, je recommande la lecture sur les différences entre expressions et déclarations dans la spécification officielle C# 5.0 ici. pour les concepts théoriques avancés qui se ramifient dans le calcul lambda, les expressions permettent le soutien des méthodes en tant qu'objets de première classe. La différence entre IQueryable et IEnumerable est centrée autour de ce point. IQueryable construit des arbres d'expression alors que IEnumerable ne le fait pas, du moins pas en termes généraux pour ceux d'entre nous qui ne travaillent pas dans les laboratoires secrets de Microsoft.

Voici un autre très utile article qui détaille les différences d'un point de vue push vs pull. (Par "push" vs "pull", je fais référence à la direction du flux de données. Réactif de Techniques de Programmation .NET et C#

voici un très bon article qui détaille les différences entre l'énoncé lambdas et expression lambdas et discute les concepts d'expression tress en plus grande profondeur: revisiter c # délégués, arbres d'expression, et lambda déclarations vs lambda expression. ."

5
répondu devinbost 2014-03-14 02:38:14

à la fois IEnumerable et IQueryable sont utilisés pour effectuer la collecte d'une donnée et effectuer des opérations de manipulation de données par exemple le filtrage sur la collecte de données. Ici vous pouvez trouver la meilleure comparaison de différence avec l'exemple. http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html enter image description here

0
répondu Jatin Phulera 2017-05-21 07:56:58

IQueryable est plus rapide que IEnumerable si nous avons affaire à des quantités énormes de données à partir de la base de données parce que,IQueryable obtient uniquement les données requises à partir de la base de données où que IEnumerable obtient toutes les données, indépendamment de la nécessité de la base de données

0
répondu arjun bollam 2018-02-27 21:58:57

ienumerable:lorsque l'on veut traiter d'inprocess de mémoire, j'.e sans dataconnection iqueryable: quand traiter avec sql server, I. e avec connexion de données ilist: opérations comme Ajouter un objet, supprimer un objet etc

-1
répondu viswanath n 2016-10-30 04:37:33