Unterschiede bei der Verwendung von IEnumerable und IQueryable als eine Art ObjectSet
Wie ich es verstehe, wenn ich die LINQ-extension-Methoden (mit lambda expression syntax) auf IQueryable
das ist in der Tat Instanz des ObjectSet
Sie sind, übersetzt LINQ to SQL-Abfragen. Was ich meine ist, dass das Kommando
IQueryable<User> users = db.UserSet;
var users32YearsOld = users.Where(user => user.Age == 32);
ist genau das gleiche wie
IQueryable<User> users = db.UserSet;
var users32YearsOld = from user in users where user.Age == 32 select user;
Also nicht von Ihnen trifft der Datenbank, bis Sie users32YearsOld
aufgezählt sind, im "Zyklus" oder so. (Hoffe ich verstehe das richtig).
Aber was wird passieren, wenn ich keine Maske, die ObjectSet
als IQueryable
aber als IEnumerable
? Also wenn der Typ es ist IEnumerable
?
IEnumerable<User> users = db.UserSet;
var users32YearsOld = users.Where(user => user.Age == 32);
Ist es treffen wird sofort auf der Datenbank (wenn ja, dann Wann ? Rechts in der ersten Zeile oder der zweiten) ? Oder wird es sich so Verhalten, wie die vorigen Befehl ist nicht der hit-Datenbank bis users32YearsOld
aufgelistet ? Gibt es einen Unterschied, wenn ich folgenden statt ?
IEnumerable<User> users = db.UserSet;
var users32YearsOld = from user in users where user.Age == 32 select user;
Danke
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gelöschten meine Antwort, weil ich es gerade getestet und es funktioniert genau wie ich es beschrieben:
Keiner erwähnt, dass Abfragen auf die Datenbank, da es keine Aufzählung. Der Unterschied zwischen
IQueryable
Abfrage undIEnumerable
Abfrage ist, dass im Falle vonIQueryable
die Filterung wird ausgeführt, auf dem Datenbank-server in der Erwägung, dass im Fall vonIEnumerable
alle Objekte von der Datenbank geladen werden, um einen Speicher und die Filterung wird durchgeführt werden .NET-code (linq-to-objects). Wie Sie sich vorstellen können, dass ist in der Regel performance-killer.Schrieb ich einfach testen, in meinem Projekt:
IEnumerable
keine Aufzählung, wennWhere(u => u.Age == 32)
berufen ist es ? Wie ist das (ich kann mir vorstellen, es funktioniert ähnlich wieIQueryable
aber wissen ist besser als raten) ?Where(u => u.Age == 32)
auf einigeIEnumerable
es nicht aufzählen, sondern nur neue erstellen enumerable-das bezieht sich auf das original und einige "where" - filter angeschlossen ? Oder wie funktioniert das ? Vielleicht sollte eine andere Frage sein...IEnumerable
undIQueryable
haben latente Ausführung). Das war der Grund, warum ich daran gezweifelt, über meine Antwort, bevor ich es getestet.IQueryable
variable, ein Baum von Objekten repräsentiert die Ausdrücke Hinzugefügt wird, das Objekt der UmsetzungIQueryable
.IQueryable
implementiertIEnumerable
, also das gleiche passiert. Wenn Sie tatsächlich aufzählen der Ausdruck, die expression tree ist ausgewertet / konvertiert in SQL an den Datenbankserver übergeben.Ist hier eine einfache Erklärung:
Wenn Sie
usersEnumerable
wenn Sie anfangen, aufzählen, über die es die zweiWhere
s werden der Reihe nach abgearbeitet; zuerst wird dieObjectSet
holt alle Objekte, und die Objekte werden gefiltert, um jenen im Alter von 32, und dann werden diese gefiltert, um diejenigen, deren name beginnt mit G.Wenn Sie
usersQueryable
die beidenWhere
s zurück, neue Objekte zu sammeln, die Auswahlkriterien, und wenn Sie beginnen Aufzählung über Sie, Sie werden übersetzen, alle Kriterien zu einer Abfrage. Dies macht einen spürbaren Unterschied.Normal, Sie brauchen keine sorgen zu machen, da Sie entweder sagen
var users
oderObjectSet users
wenn Sie deklarieren eine variable, was bedeutet, dass C# wird wissen, dass Sie daran interessiert sind, aufrufen die spezifische Methode, die aufObjectSet
, und dieIQueryable
Abfrage-operator-Methoden (Where
,Select
, ...) sind spezifischer als dieIEnumerable
Methoden. Allerdings, wenn Sie passieren, um Objekte zu MethodenIEnumerable
Parameter, die Sie vielleicht am Ende den Aufruf der falschen Methoden.Können Sie auch die Art und Weise dies funktioniert zu Ihrem Vorteil, indem die
AsEnumerable()
undAsQueryable()
Methoden beginnen mit dem anderen Ansatz. Zum Beispielvar groupedPeople = users.Where(user => user.Age > 15).AsEnumerable().GroupBy(user => user.Age);
ziehen Sie die Rechte Benutzer mit einer Datenbank-Abfrage und dann gruppieren Sie die Objekte vor Ort.Wie andere gesagt haben, es lohnt sich zu wiederholen, dass nichts passiert, bis Sie beginnen, auflisten der Sequenzen (mit
foreach
). Sie sollten jetzt verstehen, warum es konnte nicht anders sein: wenn alle Ergebnisse abgerufen werden konnten, auf einmal, konnte man nicht aufbauen-Abfragen übersetzt werden in eine effizientere Abfrage (z.B. eine SQL-Abfrage).Sind Sie richtig über IQueryable. Für IEnumerable, es treffen würde die Datenbank sofort nach der Zuweisung IEnumerable Benutzer.
Gibt es keinen wirklichen Unterschied zwischen der Verwendung von Linq-Erweiterungen vs. syntax in dem Beispiel, das Sie zur Verfügung gestellt. Manchmal die eine oder die andere bequemer sein (siehe linq-extension-Methoden-vs-linq-syntax), aber IMO geht es mehr um persönliche Vorlieben.
IEnumerable
verwendet wird, auf die Datenbank sofort und es wird die Anfrage, die alle Zeilen aus der Tabelle Benutzer oder nur jene, die das Alter festlegen zu 32 ?Der Unterschied ist, dass IEnumerable führt Sie die Audiofilter, wenn Sie mehr sind, ein zu einer Zeit. Zum Beispiel, von 100 Elementen wird in der Ausgabe 20, die durch den ersten filter und dann wird der filter zweiten mal die benötigten 10. Es wird eine Abfrage an die Datenbank, wird aber download von unnötigen Daten. Mit IQueryable wird der download wieder mit einer Abfrage, die nur die erforderlichen 10 posten. Der folgende link gibt einige ausgezeichnete Beispiele, wie man diese Abfragen funktionieren:
https://filteredcode.wordpress.com/2016/04/29/ienumerable-vs-iqueryable-part-2-practical-questions/