IEnumerable<T>
repräsentiert einen Nur-Vorwärts-Cursor von T
. .NET 3.5 fügte Erweiterungsmethoden hinzu, die LINQ standard query operators
ähnliche Where
und enthalten First
, wobei alle Operatoren, für die Prädikate oder anonyme Funktionen erforderlich sind, verwendet werden Func<T>
.
IQueryable<T>
implementiert dieselben LINQ-Standardabfrageoperatoren, akzeptiert jedoch Expression<Func<T>>
Prädikate und anonyme Funktionen. Expression<T>
ist ein kompilierter Ausdrucksbaum, eine aufgeschlüsselte Version der Methode ("halb kompiliert", wenn Sie so wollen), die vom Anbieter des Abfragbaren analysiert und entsprechend verwendet werden kann.
Beispielsweise:
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();
Im ersten Block x => x.Age > 18
befindet sich eine anonyme Methode ( Func<Person, bool>
), die wie jede andere Methode ausgeführt werden kann. Enumerable.Where
führt die Methode einmal für jede Person aus und gibt yield
Werte an, für die die Methode zurückgegeben wurde true
.
Im zweiten Block x => x.Age > 18
befindet sich ein Ausdrucksbaum ( Expression<Func<Person, bool>>
), der als "Ist die Eigenschaft 'Alter'> 18" angesehen werden kann.
Dadurch können Dinge wie LINQ-to-SQL existieren, da sie den Ausdrucksbaum analysieren und in äquivalentes SQL konvertieren können. Und da der Anbieter erst ausführen muss, wenn der IQueryable
aufgezählt ist (schließlich implementiert er IEnumerable<T>
), kann er mehrere Abfrageoperatoren (im obigen Beispiel Where
und FirstOrDefault
) kombinieren , um intelligentere Entscheidungen darüber zu treffen, wie die gesamte Abfrage für die zugrunde liegenden Daten ausgeführt werden soll Quelle (wie SELECT TOP 1
in SQL).
Sehen: