Was ist der Unterschied zwischen IQueryable und IEnumerable?
150
Ich bin verwirrt über den Unterschied. Ich bin ziemlich neu in .Net und weiß, dass ich IEnumerablesmit den Linq-Erweiterungen abfragen kann . Was ist das IQueryableund wie unterscheidet es sich?
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).
Im wirklichen Leben, wenn Sie ein ORM wie LINQ-to-SQL verwenden
Wenn Sie eine erstellen IQueryable, wird die Abfrage möglicherweise in SQL konvertiert und auf dem Datenbankserver ausgeführt
Wenn Sie eine erstellen IEnumerable, werden alle Zeilen als Objekte in den Speicher gezogen, bevor die Abfrage ausgeführt wird.
In beiden Fällen wird die Abfrage viermal für die Datenbank ausgeführt, wenn Sie eine Abfrage nicht aufrufen ToList()oder ToArray()dann bei jeder Verwendung ausgeführt werden. Wenn Sie beispielsweise eine Abfrage haben IQueryableund 4 Listenfelder daraus ausfüllen.
Auch wenn Sie Ihre Anfrage erweitern:
q.Select(x.name ="a").ToList()
Dann wird mit einem IQueryabledie generierte SQL enthalten where name = "a", aber mit IEnumerableviel mehr Rollen werden aus der Datenbank zurückgezogen, dann wird die x.name = "a"Prüfung von .NET durchgeführt.
"Abfrage kann in SQL konvertiert werden": Ich habe das "Kann sein" nicht erhalten. Wenn ich eine IEnumerable habe und eine 'komplexe Kette' erstelle, wird diese (offensichtlich) im Gegensatz zu IQueryable nicht in eine 'optimierte' SQL-Abfrage übersetzt. Ich möchte nur bestätigen, was es bedeutet, wenn Sie sagen, dass alle Zeilen in den Speicher gezogen werden. Nehmen wir an, ich habe zwei where-Klauseln. Werden dann alle Tupel der Entitäten zuerst in den Speicher abgerufen und dann wird die normale "In-Memory" -Filterung durchgeführt?
Vaibhav
36
"Der Hauptunterschied besteht darin, dass die für IQueryable definierten Erweiterungsmethoden Ausdrucksobjekte anstelle von Func-Objekten verwenden. Dies bedeutet, dass der empfangene Delegat ein Ausdrucksbaum anstelle einer aufzurufenden Methode ist. IEnumerable eignet sich hervorragend für die Arbeit mit speicherinternen Sammlungen, IQueryable jedoch für eine entfernte Datenquelle wie eine Datenbank oder einen Webdienst "
IEnumerable
IEnumerable eignet sich am besten für die Arbeit mit der In-Memory-Sammlung. IEnumerable bewegt sich nicht zwischen Elementen, sondern ist nur eine Vorwärtssammlung.
IQueryable
IQueryable eignet sich am besten für entfernte Datenquellen wie Datenbanken oder Webdienste. IQueryable ist eine sehr leistungsstarke Funktion, die eine Vielzahl interessanter Szenarien für die verzögerte Ausführung ermöglicht (z. B. Paging- und kompositionsbasierte Abfragen).
Wenn Sie also einfach die In-Memory-Sammlung durchlaufen müssen, verwenden Sie IEnumerable. Wenn Sie die Sammlung wie Dataset und andere Datenquellen bearbeiten möchten, verwenden Sie IQueryable
Der Hauptunterschied besteht darin, dass IEnumerable ständig alle seine Elemente auflistet, während IQueryable Elemente auflistet oder sogar andere Dinge basierend auf einer Abfrage ausführt. Die Abfrage ist ein Ausdruck (eine Datendarstellung von .NET-Code), den ein IQueryProvider untersuchen / interpretieren / kompilieren / was auch immer muss, um Ergebnisse zu generieren.
Ein Abfrageausdruck bietet zwei Vorteile.
Der erste Vorteil ist die Optimierung. Da Modifikatoren wie 'Where' im Abfrageausdruck enthalten sind, kann der IQueryProvider ansonsten unmögliche Optimierungen anwenden. Anstatt alle Elemente zurückzugeben und dann die meisten aufgrund einer 'Where'-Klausel wegzuwerfen, könnte der Anbieter eine Hash-Tabelle verwenden, um Elemente mit einem bestimmten Schlüssel zu finden.
Der zweite Vorteil ist die Flexibilität. Da Ausdrücke explorierbare Datenstrukturen sind, können Sie beispielsweise die Abfrage serialisieren und an einen Remotecomputer (z. B. linq-to-sql) senden.
Erstens werden IEnumerable in einem System.Collections-Namespace gefunden, während IQueryable in einem System.Linq-Namespace gefunden werden. Wenn Sie IEnumerable verwenden, wenn Sie Daten aus In-Memory-Sammlungen wie List, Array-Sammlung usw. abfragen. Wenn Sie Daten aus Out-Memory-Sammlungen (wie Remote-Datenbank, Service) abfragen, verwenden Sie IQueryable. Während IEnumerable beim Abfragen von Daten aus der Datenbank eine Auswahlabfrage auf der Serverseite ausführt, Daten auf der Clientseite in den Speicher lädt und dann Daten filtert. Daher macht mehr Arbeit und wird langsam. Beim Abfragen von Daten aus der Datenbank führt IQueryable eine Auswahlabfrage auf der Serverseite mit allen Filtern aus. Daher macht weniger Arbeit und wird schnell.
Im wirklichen Leben, wenn Sie ein ORM wie LINQ-to-SQL verwenden
IQueryable
, wird die Abfrage möglicherweise in SQL konvertiert und auf dem Datenbankserver ausgeführtIEnumerable
, werden alle Zeilen als Objekte in den Speicher gezogen, bevor die Abfrage ausgeführt wird.In beiden Fällen wird die Abfrage viermal für die Datenbank ausgeführt, wenn Sie eine Abfrage nicht aufrufen
ToList()
oderToArray()
dann bei jeder Verwendung ausgeführt werden. Wenn Sie beispielsweise eine Abfrage habenIQueryable
und 4 Listenfelder daraus ausfüllen.Auch wenn Sie Ihre Anfrage erweitern:
Dann wird mit einem
IQueryable
die generierte SQL enthaltenwhere name = "a"
, aber mitIEnumerable
viel mehr Rollen werden aus der Datenbank zurückgezogen, dann wird diex.name = "a"
Prüfung von .NET durchgeführt.quelle
"Der Hauptunterschied besteht darin, dass die für IQueryable definierten Erweiterungsmethoden Ausdrucksobjekte anstelle von Func-Objekten verwenden. Dies bedeutet, dass der empfangene Delegat ein Ausdrucksbaum anstelle einer aufzurufenden Methode ist. IEnumerable eignet sich hervorragend für die Arbeit mit speicherinternen Sammlungen, IQueryable jedoch für eine entfernte Datenquelle wie eine Datenbank oder einen Webdienst "
Quelle: hier
quelle
IEnumerable IEnumerable eignet sich am besten für die Arbeit mit der In-Memory-Sammlung. IEnumerable bewegt sich nicht zwischen Elementen, sondern ist nur eine Vorwärtssammlung.
IQueryable IQueryable eignet sich am besten für entfernte Datenquellen wie Datenbanken oder Webdienste. IQueryable ist eine sehr leistungsstarke Funktion, die eine Vielzahl interessanter Szenarien für die verzögerte Ausführung ermöglicht (z. B. Paging- und kompositionsbasierte Abfragen).
Wenn Sie also einfach die In-Memory-Sammlung durchlaufen müssen, verwenden Sie IEnumerable. Wenn Sie die Sammlung wie Dataset und andere Datenquellen bearbeiten möchten, verwenden Sie IQueryable
quelle
Der Hauptunterschied besteht darin, dass IEnumerable ständig alle seine Elemente auflistet, während IQueryable Elemente auflistet oder sogar andere Dinge basierend auf einer Abfrage ausführt. Die Abfrage ist ein Ausdruck (eine Datendarstellung von .NET-Code), den ein IQueryProvider untersuchen / interpretieren / kompilieren / was auch immer muss, um Ergebnisse zu generieren.
Ein Abfrageausdruck bietet zwei Vorteile.
Der erste Vorteil ist die Optimierung. Da Modifikatoren wie 'Where' im Abfrageausdruck enthalten sind, kann der IQueryProvider ansonsten unmögliche Optimierungen anwenden. Anstatt alle Elemente zurückzugeben und dann die meisten aufgrund einer 'Where'-Klausel wegzuwerfen, könnte der Anbieter eine Hash-Tabelle verwenden, um Elemente mit einem bestimmten Schlüssel zu finden.
Der zweite Vorteil ist die Flexibilität. Da Ausdrücke explorierbare Datenstrukturen sind, können Sie beispielsweise die Abfrage serialisieren und an einen Remotecomputer (z. B. linq-to-sql) senden.
quelle
IQueriable ist dasselbe wie IEnumerable, bietet jedoch zusätzliche Funktionen zum Implementieren von benutzerdefinierten Abfragen mit Linq. Hier ist eine Beschreibung auf MSDN: http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
quelle
Erstens werden IEnumerable in einem System.Collections-Namespace gefunden, während IQueryable in einem System.Linq-Namespace gefunden werden. Wenn Sie IEnumerable verwenden, wenn Sie Daten aus In-Memory-Sammlungen wie List, Array-Sammlung usw. abfragen. Wenn Sie Daten aus Out-Memory-Sammlungen (wie Remote-Datenbank, Service) abfragen, verwenden Sie IQueryable. Während IEnumerable beim Abfragen von Daten aus der Datenbank eine Auswahlabfrage auf der Serverseite ausführt, Daten auf der Clientseite in den Speicher lädt und dann Daten filtert. Daher macht mehr Arbeit und wird langsam. Beim Abfragen von Daten aus der Datenbank führt IQueryable eine Auswahlabfrage auf der Serverseite mit allen Filtern aus. Daher macht weniger Arbeit und wird schnell.
quelle