IEnumerable<T>
représente un curseur à l'avance de T
. .NET 3.5 a ajouté des méthodes d'extension incluant l'élément LINQ standard query operators
comme Where
y First
avec tous les opérateurs qui nécessitent des prédicats ou des fonctions anonymes. 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 les fonctions anonymes. Expression<T>
est un arbre d'expression compilé, une version décomposée de la méthode ("demi-compilée" si vous voulez) qui peut être analysée par le fournisseur de la table d'interrogation et utilisée 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ée comme toute autre méthode. Enumerable.Where
exécutera la méthode une fois pour chaque personne, yield
les valeurs pour lesquelles la méthode a retourné true
.
Dans le deuxième bloc, x => x.Age > 18
est un arbre d'expression ( Expression<Func<Person, bool>>
), qui peut être considéré comme "la propriété 'Age' est-elle > 18".
Cela permet à des choses comme LINQ-to-SQL d'exister car elles peuvent analyser l'arbre d'expression et le convertir en SQL équivalent. Et parce que le fournisseur n'a pas besoin de s'exécuter jusqu'à ce que la requête IQueryable
est énuméré (il implémente IEnumerable<T>
après tout), il peut combiner plusieurs opérateurs de requête (dans l'exemple ci-dessus Where
y FirstOrDefault
) pour faire des choix plus intelligents sur la façon d'exécuter la requête entière contre la source de données sous-jacente (comme l'utilisation de SELECT TOP 1
en SQL).
Voir :