Frage

Ich bin in Bezug auf die Differenz verwirrt. ziemlich neu in .Net zu sein, ich weiß, ich IEnumerables mit den Linq Erweiterungen abfragen. Was also ist das IQueryable und wie funktioniert es unterscheiden?


Siehe auch Was ist der Unterschied zwischen IQueryable [T] und IEnumerable [T]? dass Überschneidungen mit dieser Frage.

War es hilfreich?

Lösung

stellt IEnumerable<T> einen Vorwärts-Cursor von T. .NET 3.5 Erweiterungsmethoden hinzugefügt, die die LINQ standard query operators wie Where und First enthalten, mit allen Operatoren, die Prädikate oder anonyme Funktionen unter Func<T> benötigen.

IQueryable<T> Geräte die gleichen LINQ Standardabfrageoperatoren, akzeptiert aber Expression<Func<T>> für Prädikate und anonyme Funktionen. Expression<T> ist eine kompilierte Ausdrucksbaum, eine aufgebrochene Version des Verfahrens ( „Halb zusammengestellt“, wenn man so will), die entsprechend durch die abfragbaren des Anbieters und verwendet analysiert werden kann.

Zum Beispiel:

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 ist ein anonymes Verfahren (Func<Person, bool>), die wie jedes andere Verfahren ausgeführt werden kann. Enumerable.Where wird die Methode einmal für jede Person ausführen, Werte yielding, für die das Verfahren true zurückgegeben.

Im zweiten Block, x => x.Age > 18 ist ein Ausdruck Baum (Expression<Func<Person, bool>>), die gedacht werden kann als „ist das‚Alter‘Eigentum> 18“.

Auf diese Weise kann Dinge wie LINQ to SQL existieren, weil sie den Ausdrucksbaum analysieren können und es in äquivalente SQL konvertieren. Und da der Anbieter nicht ausgeführt werden muss, bis die IQueryable aufgezählt wird (es implementiert IEnumerable<T>, nachdem alle), kann es mehrere Abfrageoperator kombinieren (im obigen Beispiel Where und FirstOrDefault) intelligentere Entscheidungen zu treffen, wie die gesamte Abfrage auszuführen gegen die zugrunde liegende Datenquelle (wie SELECT TOP 1 in SQL verwenden).

Siehe auch:

Andere Tipps

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

  • Wenn Sie einen IQueryable erstellen, dann die Abfrage in SQL umgewandelt werden und auf dem Datenbankserver ausführen
  • Wenn Sie einen IEnumerable erstellen, dann werden alle Zeilen als Objekte in den Speicher gezogen werden, bevor die Abfrage ausgeführt wird.

In beiden Fällen, wenn Sie rufen Sie nicht ein ToList() oder ToArray() dann Abfrage jedes Mal ausgeführt werden, verwendet wird, so, sagen wir, Sie haben eine IQueryable und Sie füllen 4 Listenfelder von ihm, dann wird die Abfrage ausgeführt sein gegen die Datenbank 4 mal.

Auch wenn Sie erweitern Ihre Abfrage:

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

Dann mit einem IQueryable die generierten SQL-where name = "a" enthalten, aber mit einem IEnumerable vielen weiteren Rollen aus der Datenbank zurück gezogen werden, dann wird die x.name = "a" Prüfung durch .NET erfolgen.

"Der wesentliche Unterschied besteht darin, dass die Erweiterungsmethoden für IQueryable take Expression definierte Objekte statt Func-Objekte, dh der Delegierte erhält er ist ein Ausdruck Baum anstelle einer Methode aufzurufen. IEnumerable ist für die Arbeit mit In-Memory-Sammlungen, aber IQueryable ermöglicht eine Remote-Datenquelle, wie eine Datenbank oder Web-Service "

Quelle: hier

IEnumerable IEnumerable ist am besten geeignet ist, mit In-Memory-Sammlung zu arbeiten. IEnumerable nicht zwischen den einzelnen Posten bewegen, ist es nur vorwärts Sammlung.

IQueryable IQueryable besten für Remote-Datenquelle, wie eine Datenbank oder Web-Service. IQueryable ist eine sehr leistungsstarke Funktion, die eine Vielzahl von interessanten verzögerte Ausführung Szenarien (wie Paging und Zusammensetzung basierten Abfragen) ermöglicht.

Wenn Sie also einfach Iterierte haben durch die In-Memory-Erfassung, Verwendung IEnumerable, wenn Sie eine Manipulation mit der Sammlung wie Dataset und anderen Datenquellen zu tun, verwendet IQueryable

Der prinzipielle Unterschied besteht darin, dass IEnumerable alle seine Elemente die ganze Zeit aufzählen, während IQueryable Elemente aufzählen werden, oder auch andere Dinge tun, basierend auf einer Abfrage. Die Abfrage ist ein Ausdruck (eine Datendarstellung von .NET-Code), die eine IQueryProvider muß erforschen / interpretieren / Kompilierung / was auch immer, um Ergebnisse zu erzeugen.

einen Abfrageausdruck zu haben, gibt zwei Vorteile.

Der erste Vorteil ist die Optimierung. Da Modifikatoren wie ‚Wo‘ in dem Abfrageausdruck enthalten sind, können die IQueryProvider gelten sonst unmöglich Optimierungen. Statt alle Elemente der Rückkehr dann die meisten von ihnen Wegwerfen aufgrund eines ‚Wo‘ -Klausel, könnte der Anbieter eine Hash-Tabelle verwenden, um Elemente mit einem bestimmten Schlüssel zu suchen.

Der zweite Vorteil ist die Flexibilität. Da Ausdrücke erforschbaren Datenstrukturen sind, können Sie Dinge wie serialize tun, um die Abfrage und es zu einem Remote-Computer senden (zB. Linq-to-SQL).

IQueriable ist die gleiche wie IEnumerable sondern bietet auch zusätzliche Funktionen zu implementieren individuellen mit Linq abfragt. Hier ist die Beschreibung auf MSDN: http://msdn.microsoft. com / en-us / library / system.linq.iqueryable.aspx

Zur einem IEnumerable in einem System.Collections-Namespace gefunden, während die IQueryable in einem System.Linq Namespace zu finden sind. Wenn Sie IEnumerable verwenden, wenn Daten von In-Memory-Sammlungen wie Liste, Array Sammlung usw. abfragen und wenn Daten von Out-Speicher (wie Remote-Datenbank, Service) Sammlungen Abfragen, so dass Sie verwenden IQueryable sind. Da Während der Daten aus der Datenbank abfragen, führt IEnumerable Auswahlabfrage auf Serverseite, Lastdaten im Speicher auf Client-Seite und dann Filterdaten. Daher macht mehr Arbeit und wird langsam. Während die Daten aus der Datenbank abfragen, führen IQueryable Auswahlabfrage auf Server-Seite mit allen Filtern. Daher macht weniger Arbeit und wird zu schnell.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top