Question

Je suis confus quant à la différence. Être assez nouveau pour .Net, je sais que je peux interroger IEnumerables en utilisant les extensions Linq. Quel est donc ce IQueryable et comment fonctionne-t-il différent?


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

Était-ce utile?

La solution

IEnumerable<T> représente un curseur uniquement de T. .NET 3.5 a ajouté des méthodes d'extension qui comprenaient la LINQ standard query operators comme Where et First, avec tous les opérateurs qui nécessitent des prédicats ou des fonctions anonymes prenant Func<T>.

IQueryable<T> met en œuvre les mêmes opérateurs de requête standard LINQ, mais accepte Expression<Func<T>> pour les prédicats et fonctions anonymes. Expression<T> est un arbre d'expression compilé, une version désagrégée de la méthode ( « demi-compilé » si vous voulez) qui peut être analysé par le fournisseur du interrogeable et utilisé en conséquence.

Par exemple:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

Dans le premier bloc, x => x.Age > 18 est une méthode anonyme (Func<Person, bool>), qui peut être exécuté comme une autre méthode. Enumerable.Where exécutera la méthode une fois pour chaque personne, les valeurs yielding pour lesquelles la méthode renvoyait true.

Dans le second bloc, x => x.Age > 18 est un arbre d'expression (de Expression<Func<Person, bool>>), qui peut être considéré comme « est la propriété « âge »> 18 ».

Cela permet à des choses comme LINQ to SQL d'exister, car ils peuvent analyser l'arbre d'expression et le convertir en équivalent SQL. Et parce que le fournisseur n'a pas besoin d'exécuter jusqu'à ce que le IQueryable est dénombrée (il met en œuvre IEnumerable<T>, après tout), il peut combiner plusieurs opérateurs de requête (dans l'exemple ci-dessus Where et FirstOrDefault) de faire des choix plus intelligents sur la façon d'exécuter toute requête contre la source de données sous-jacentes (comme l'utilisation SELECT TOP 1 dans SQL).

Voir:

  • Le standard .NET de requête Opérateurs

Autres conseils

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

  • Si vous créez un IQueryable, la requête peut être converti en SQL et exécutée sur le serveur de base de données
  • Si vous créez un IEnumerable, puis toutes les lignes seront intégrés dans la mémoire comme des objets avant d'exécuter la requête.

Dans les deux cas, si vous ne l'appelez pas un ToList() ou ToArray() alors la requête sera exécutée chaque fois qu'il est utilisé, donc, par exemple, vous avez un IQueryable et vous remplissez 4 zones de liste de, alors la requête sera exécutée contre la base de données 4 fois.

Aussi, si vous prolongez votre requête:

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

Ensuite, avec un IQueryable le SQL généré contiendra where name = "a", mais avec un IEnumerable beaucoup plus de rôles seront tirés en arrière à partir de la base de données, le contrôle de x.name = "a" sera fait par .NET.

"La principale différence est que les méthodes d'extension définies pour IQueryable prennent l'expression des objets au lieu d'objets Func, ce qui signifie le délégué qu'il reçoit est un arbre d'expression au lieu d'une méthode pour invoquer. IEnumerable est idéal pour travailler avec des collections en mémoire, mais IQueryable permet une source de données à distance, comme une base de données ou un service web "

Source:

IEnumerable IEnumerable est le mieux adapté pour travailler avec la collection en mémoire. IEnumerable ne se déplace pas entre les éléments, il est en avant la seule collection.

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

Alors, quand vous devez simplement itérer la collection en mémoire, utilisez IEnumerable, si vous devez faire une manipulation avec la collection comme Dataset et d'autres sources de données, utilisez IQueryable

La principale différence est que IEnumerable va énumérer tous ses éléments tout le temps, alors que IQueryable va énumérer les éléments, ou même faire d'autres choses, sur la base d'une requête. La requête est une expression (une représentation de données code .Net), qui doit explorer un IQueryProvider / interpréter / compiler / whatever afin de générer des résultats.

Avoir une expression de requête donne deux avantages.

Le premier avantage est l'optimisation. Parce que modificateurs comme « Où » sont inclus dans l'expression de requête, IQueryProvider peut appliquer des optimisations autrement impossibles. Au lieu de renvoyer tous les éléments puis jeter la plupart d'entre eux en raison d'une clause « Où », le fournisseur peut utiliser une table de hachage pour trouver des éléments avec une clé donnée.

Le deuxième avantage est la flexibilité. Parce que les expressions sont des structures de données explorables, vous pouvez faire des choses comme sérialiser la requête et l'envoyer à une machine distante (par exemple. LINQ to SQL).

IQueriable est le même que IEnumerable mais il fournit également des fonctionnalités supplémentaires pour mettre en œuvre l'interrogation personnalisée avec LINQ. Voici la description sur MSDN: http://msdn.microsoft. com / fr-fr / bibliothèque / system.linq.iqueryable.aspx

Tout d'abord IEnumerable se trouvent dans un System.Collections, espace de noms alors que le IQueryable se trouvent dans un System.Linq espace de noms. Si vous êtes l'utilisation IEnumerable lors de l'interrogation des données de collections en mémoire comme liste, collection Array etc Et lors de l'interrogation des données de l'extérieur de la mémoire (comme base de données distante, service) collections donc vous utilisez IQueryable. Parce que les données lors de l'interrogation de la base de données, IEnumerable exécuter la requête de sélection sur le côté serveur, les données de charge en mémoire sur le côté client, puis filtrer les données. D'où le fait plus de travail et devient lent. Bien que l'interrogation des données de base de données, IQueryable exécuter la requête de sélection sur le côté serveur avec tous les filtres. D'où le fait moins de travail et devient rapide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top