Update: Sie haben Ihren Titel behoben, also ignorieren Sie die Rant.
Der Titel Ihrer Frage hat nichts mit Ihren Codebeispielen zu tun. Ihre Frage impliziert, dass eine Syntax IEnumerable und die andere IQueryable ist, aber das ist falsch. Wenn in Ihren Beispielen db.Surveys
ein IQueryable ist, dann beide Ihre Proben verwenden IQueryable. Ich werde versuchen, beide Fragen zu beantworten.
Ihre beiden Codebeispiele sind nur unterschiedliche Möglichkeiten zum Schreiben der gleichen LINQ-Abfragen (vorausgesetzt, sie sind gut geschrieben). Der Code in Beispiel 1 ist nur eine Kurzform für den Code in Beispiel 2. Der Compiler behandelt den Code in beiden Beispielen auf die gleiche Weise. Denken Sie an die Art und Weise, wie der C# -Compiler int?
genauso behandelt wie Nullable<System.Int32>
. Sowohl die C# - als auch die VB.Net-Sprachen stellen diese Abkürzungssyntax bereit. Andere Sprachen haben möglicherweise diese Syntax nicht und Sie müssten die Syntax von Beispiel 2 verwenden. Tatsächlich unterstützen andere Sprachen möglicherweise nicht einmal Erweiterungsmethoden oder Lambda-Ausdrücke, und Sie müssten noch eine hässlichere Syntax verwenden.
Update:
Um Sander Beispiel zu nehmen, wenn Sie diese (Abfrage-Syntax) schreiben:
var surveyNames = from s in db.Surveys select s.Name
Sie denken, der Compiler dreht, dass eine Abkürzung in diese (Erweiterungsmethoden und Lambda-Ausdruck):
IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name);
Aber eigentlich sind Erweiterungsmethoden und Lambda-Ausdrücke selbst Kürzel.Die Compiler emittieren so etwas wie diese (nicht genau, aber nur eine Idee zu geben):
Expression<Func<Survey, string>> selector = delegate(Survey s) { return s.Name; };
IQueryable<string> surveryNames = Queryable.Select(db.Surveys, selector);
Beachten Sie, dass Select()
ist nur eine statische Methode in der Queryable
Klasse. Wenn Ihre .NET-Sprache keine Abfragesyntax, Lambdas oder Erweiterungsmethoden unterstützt, müssen Sie den Code selbst schreiben.
Was sind die Vorteile von einem Stil über die andere verwenden?
Für kleine Abfragen Erweiterungsmethoden kann kompakter sein:
var items = source.Where(s => s > 5);
Auch kann die Erweiterungsmethode Syntax flexibler sein, wie bedingte WHERE-Klauseln:
var items = source.Where(s => s > 5);
if(smallerThanThen)
items = items.Where(s => s < 10);
if(even)
items = items.Where(s => (s % 2) == 0);
return items.OrderBy(s => s);
Zusätzlich , mehrere Methoden sind nur über die Syntax der Erweiterungsmethode (Count(), Aggregate(), Take(), Skip(), ToList(), ToArray() usw.) verfügbar. Wenn ich also eines davon verwende, In der Regel schreibe ich die gesamte Abfrage in diese Syntax, um eine Vermischung zu vermeiden. b andere Syntaxen.
var floridaCount = source.Count(s => s.State == "FL");
var items = source
.Where(s => s > 5)
.Skip(5)
.Take(3)
.ToList();
Auf der anderen Seite, wenn eine Abfrage größer und komplexer wird, Abfrage-Syntax kann klarer sein, vor allem, wenn Sie mit ein paar let
, group
, join
usw.
In der verkomplizieren starten Ende werde ich normalerweise verwenden, was für jede spezifische Abfrage besser funktioniert.
Update: Sie Ihren Titel festgelegt, so ignoriert den Rest ...
Nun, über Ihren Titel: In Bezug auf LINQ, IEnumerable und IQueryable sind sehr ähnlich. Sie haben beide die gleichen Erweiterungsmethoden (Select, Where, Count, usw.), wobei der Hauptunterschied (nur?) Darin besteht, dass IEnumerable Func<TIn,TOut>
als Parameter und IQueryable Expression<Func<TIn,TOut>>
als Parameter verwendet. Sie drücken beide den gleichen Weg aus (normalerweise Lamba-Ausdrücke), aber innerlich sind sie völlig verschieden.
IEnumerable ist der Eingang zu LINQ to Objects. Die LINQ to Objects-Erweiterungsmethoden können auf jedem IEnumerable (Arrays, Listen, alles, was Sie mit iterieren können) aufgerufen werden, und die Func<TIn,TOut>
wird zur Kompilierungszeit in IL konvertiert und läuft zur Laufzeit wie ein normaler Methodencode. Beachten Sie, dass einige andere LINQ-Anbieter IEnumerable verwenden und daher LINQ to Objects im Hintergrund verwenden (LINQ to XML, LINQ to DataSet).
IQQueryable wird von LINQ to SQL, LINQ to Entities und anderen LINQ-Anbietern verwendet, die Ihre Abfrage untersuchen und übersetzen müssen, anstatt den Code direkt auszuführen. IQueryable-Abfragen und ihre Expression<Func<TIn,TOut>>
s werden zur Kompilierungszeit nicht in IL kompiliert. Stattdessen wird ein Ausdrucksbaum erstellt und kann zur Laufzeit untersucht werden. Dadurch können die Anweisungen in andere Abfragesprachen (z. B. T-SQL) übersetzt werden. Ein Ausdrucksbaum kann zur Laufzeit in eine Func < TIn, TOut > kompiliert und bei Bedarf ausgeführt werden.
Ein Beispiel, das den Unterschied veranschaulicht, finden Sie unter this question, wo das OP einen Teil einer LINQ to SQL-Abfrage in SQL Server ausführen, die Objekte in verwalteten Code bringen und den Rest der Abfrage in LINQ to Objects erledigen soll . Um dies zu erreichen, muss er nur das IQueryable in ein IEnumerable umwandeln, wo er den Wechsel durchführen möchte.
seine erwähnenswert Ihre Proben sind nicht für nicht identisch ... –
Auch die .ToList() am Ende Kräfte ganz andere Ausführung. Lassen Sie sie aus, um sie äquivalent zu machen. Das erste x ist vom Typ IQueryable und das zweite ist IList . –