wake-up-neo.com

Was ist der Unterschied zwischen IQueryable und IEnumerable

Ich bin verwirrt über den Unterschied. Ich bin ziemlich neu in .Net und weiß, dass ich IEnumerables mit den Linq-Erweiterungen abfragen kann. Also, was ist das IQueryable und wie unterscheidet es sich?


Siehe auch Was ist der Unterschied zwischen IQueryable [T] und IEnumerable [T]? , der sich mit dieser Frage überschneidet.

145
James Hay

IEnumerable<T> repräsentiert einen Nur-Vorwärts-Cursor von T. .NET 3.5 fügte Erweiterungsmethoden hinzu, die das LINQ standard query operators wie Where und First, wobei alle Operatoren, die Prädikate oder anonyme Funktionen benötigen, Func<T>.

IQueryable<T> implementiert dieselben LINQ-Standardabfrageoperatoren, akzeptiert jedoch Expression<Func<T>> für Prädikate und anonyme Funktionen. Expression<T> ist ein kompilierter Ausdrucksbaum, eine getrennte Version der Methode ("halb kompiliert", wenn Sie so wollen), die vom Provider des abfragbaren Objekts 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 wird x => x.Age > 18 ist 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, yielding Werte, für die die Methode true zurückgegeben hat.

Im zweiten Block, x => x.Age > 18 ist ein Ausdrucksbaum (Expression<Func<Person, bool>>), was als "ist die 'Age'-Eigenschaft> 18" angesehen werden kann.

Dies ermöglicht die Existenz von Dingen wie LINQ-to-SQL, da sie den Ausdrucksbaum analysieren und in äquivalentes SQL konvertieren können. Und weil der Provider nicht ausgeführt werden muss, bis das IQueryable aufgezählt ist (es implementiert IEnumerable<T>, schließlich), kann es mehrere Abfrageoperatoren (im obigen Beispiel Where und FirstOrDefault) kombinieren, um klügere Entscheidungen darüber zu treffen, wie die gesamte Abfrage für die zugrunde liegende Datenquelle ausgeführt werden soll (z. B. mit SELECT TOP 1 in SQL).

Sehen:

183
Richard Szalay

Im wirklichen Leben, wenn Sie ein ORM wie LINQ-to-SQL verwenden

  • Wenn Sie ein IQueryable erstellen, wird die Abfrage möglicherweise in SQL konvertiert und auf dem Datenbankserver ausgeführt
  • Wenn Sie ein IEnumerable erstellen, werden alle Zeilen als Objekte in den Speicher abgerufen, bevor die Abfrage ausgeführt wird.

Wenn Sie in beiden Fällen kein ToList() oder ToArray() aufrufen, wird die Abfrage bei jeder Verwendung ausgeführt, dh, Sie haben ein IQueryable und Wenn Sie 4 Listenfelder ausfüllen, wird die Abfrage viermal für die Datenbank ausgeführt.

Auch wenn Sie Ihre Anfrage erweitern:

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

Dann enthält die generierte SQL mit einem IQueryablewhere name = "a", aber mit einem IEnumerable werden viel mehr Rollen aus der Datenbank zurückgezogen, dann wird der x.name = "a" wird von .NET geprüft.

79
Ian Ringrose

"Der Hauptunterschied besteht darin, dass die für IQueryable definierten Erweiterungsmethoden Expression-Objekte anstelle von Func-Objekten verwenden, was bedeutet, dass der Delegat, den er empfängt, eine Ausdrucksbaumstruktur anstelle einer aufzurufenden Methode ist. IEnumerable eignet sich hervorragend für die Arbeit mit speicherinternen Auflistungen, IQueryable lässt dies jedoch zu für eine entfernte Datenquelle, wie eine Datenbank oder einen Webdienst "

Quelle: hier

36
Gabe

IEnumerable IEnumerable eignet sich am besten für die Arbeit mit speicherinternen Auflistungen. IEnumerable bewegt sich nicht zwischen Elementen, sondern ist nur eine Weiterleitungssammlung.

IQueryable IQueryable eignet sich am besten für entfernte Datenquellen wie Datenbanken oder Webservices. IQueryable ist eine sehr leistungsstarke Funktion, die eine Vielzahl interessanter verzögerter Ausführungsszenarien ermöglicht (wie Abfragen auf der Basis von Paging und Kompositionen).

Wenn Sie also einfach die speicherinterne Auflistung durchlaufen müssen, verwenden Sie IEnumerable. Wenn Sie Änderungen an der Auflistung wie Dataset und anderen Datenquellen vornehmen müssen, verwenden Sie IQueryable

18
Talha

Der Hauptunterschied besteht darin, dass IEnumerable immer alle seine Elemente auflistet, während IQueryable auf der Grundlage einer Abfrage Elemente auflistet oder sogar andere Aktionen ausführt. Die Abfrage ist ein Ausdruck (eine Datendarstellung von .Net-Code), den ein IQueryProvider durchsuchen/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 vornehmen. Anstatt alle Elemente zurückzugeben und die meisten aufgrund einer 'Where'-Klausel wegzuwerfen, könnte der Anbieter eine Hash-Tabelle verwenden, um Elemente mit einem bestimmten Schlüssel zu lokalisieren.

Der zweite Vorteil ist die Flexibilität. Da Ausdrücke explizite Datenstrukturen sind, können Sie die Abfrage beispielsweise serialisieren und an einen Remotecomputer senden (z. B. linq-to-sql).

9
Craig Gidney

Erstens befinden sich IEnumerable in einem System.Collections-Namespace, während sich IQueryable in einem System.Linq-Namespace befindet. Wenn Sie IEnumerable verwenden, wenn Sie Daten aus speicherinternen Sammlungen wie List, Array Collection usw. abfragen, und wenn Sie Daten aus speicherinternen Sammlungen (wie Remote-Datenbank, Dienst) abfragen, verwenden Sie IQueryable. Weil IEnumerable beim Abfragen von Daten aus der Datenbank eine Auswahlabfrage auf der Serverseite ausführt, Daten auf der Clientseite im Arbeitsspeicher lädt und dann Daten filtert. Macht also mehr Arbeit und wird langsam. Beim Abfragen von Daten aus der Datenbank führt IQueryable eine Auswahlabfrage auf der Serverseite mit allen Filtern aus. Macht also weniger Arbeit und wird schnell.

1
Nayeem Mansoori

IQueriable ist dasselbe wie IEnumerable, bietet jedoch zusätzliche Funktionen zum Implementieren von benutzerdefinierten Abfragen mit Linq. Hier finden Sie eine Beschreibung zu MSDN: http://msdn.Microsoft.com/en-us/library/system.linq.iqueryable.aspx

1
Andrew Bezzub