IEnumerable<T>repräsentiert einen Nur-Vorwärts-Cursor von T. .NET 3.5 fügte Erweiterungsmethoden hinzu, die LINQ standard query operatorsähnliche Whereund 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 > 18befindet sich eine anonyme Methode ( Func<Person, bool>), die wie jede andere Methode ausgeführt werden kann. Enumerable.Whereführt die Methode einmal für jede Person aus und gibt yieldWerte an, für die die Methode zurückgegeben wurde true.
Im zweiten Block x => x.Age > 18befindet 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 IQueryableaufgezählt ist (schließlich implementiert er IEnumerable<T>), kann er mehrere Abfrageoperatoren (im obigen Beispiel Whereund 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 1in SQL).
Sehen: