2010-08-17 17 views
8

Ich habe dies:Was ist der Unterschied zwischen IOrderedQueryable und IQueryable?

var points = from p in ContextDB.Points 
       orderby p.PointInTime descending 
       where p.InstanceID == instanceId 
       && p.ParentPointID == null 
       && p.PointTypeID == currentPointTypeID 
       select p; 

und diese:

var points = from p in ContextDB.Points 
       where p.InstanceID == instanceId 
       && p.ParentPointID == null 
       && p.PointTypeID == currentPointTypeID 
       orderby p.PointInTime descending 
       select p; 

Während ich die Verwendung von beiden (und ein generiert einen Fehler später) Ich verstehe nicht, zu verstehen, wie sie anders sind.

Ich habe Fragen wie diese an anderer Stelle auf STO gesehen, aber ich habe nicht gefunden, was die Antwort auf diese Frage ist, fürchte ich.

+1

Können Sie den Code anzeigen, der den Fehler anzeigt? – Lazarus

Antwort

4

Ein Typ, der IOrderedQueryable<T> implementiert, enthält einen zusätzlichen Status, der Informationen zum Sortieren enthält.

IQueryable<T> stellt normalerweise eine Operation dar, die später ausgeführt wird (und möglicherweise in einer vollständig anderen Sprache auf einem anderen Computer, z. B. mit LINQ to SQL). Eine separate Schnittstelle wird benötigt, da die nächste Operation möglicherweise eine andere Sortierung ist, die anders behandelt werden muss (um nach Spalte A zu sortieren, und B zwei LINQ-Operatoren benötigt, um zu definieren), aber das System muss sicherstellen, dass jeder Schlüssel dazu beiträgt die Gesamtsorte).

+1

Ich bin nicht sicher, ob dies korrekt ist, da die IOrderedQueryable-Schnittstelle nur eine Marker-Schnittstelle ist (siehe http://msdn.microsoft.com/en-us/library/bb340178.aspx). Also ich denke, es enthält nur die Information, dass die Liste sortiert ist, aber keine anderen Informationen über die Sortierung selbst. – Gerwald

+0

@leo: Ob ein bestimmter LINQ-Provider dies als Markierung verwendet (und nachfolgende "ThenBy" -/"ThenByDescending" -Aufrufe zulässt) oder ob das zurückgegebene Objekt wirklich anders ist, ist ein Implementierungsdetail. In LINQ to Objects ist es ein anderer Typ (versuchen Sie, Ihre eigene Implementierung zu machen), aber klarerweise werden andere Anbieter (zB um SQL zu generieren) sehr unterschiedliche Ansätze haben. Zusammenfassung: Es bietet einem Anbieter die Möglichkeit, eine andere Implementierung für die Sortieroperatoren zu verwenden, erfordert dies jedoch nicht. – Richard

0

IOrderedQuery das Ergebnis einer Abfrage, die zu einer bestimmten Reihenfolge führt, und IQueryable enthält Elemente in einer unbestimmten Reihenfolge.

+0

Habe ich richtig gedacht, dass das erste Codebeispiel nichts bestellen wird? Wenn ja, was bringt es, "orderby" vor 'wo' zu verwenden? –

+0

@ Matt-W: Wir müssten uns den Ausdrucksbaum ansehen, um zu bestimmen, wie genau jede Abfrage verarbeitet wird. Ich vermute, dass es die erste Abfrage ist, die den Fehler für Sie generiert. Es wäre nicht die erste oder die einzige Linq-Abfrage, die Sie ohne Fehler schreiben und kompilieren können, die dann während der Ausführung fehlschlägt, das ist die Natur von Linq. – Lazarus

2

Es ist leicht zu sehen, wenn Sie das Query-Verständnis in die entsprechenden Linq-Erweiterungsmethoden übersetzen. Der Rückgabetyp von OrderBy() ist IOrderedEnumerable <>. Where() gibt IEnumerable <> zurück. Was Ihr erster Ausdruck tut, sortieren Sie zuerst der Punkte und wählen dann nur diejenigen aus, die der where-Klausel entsprechen. Die zuletzt angewendete Operation ist Where, daher ist der Ausdruckstyp IEnumerable <>.

Welche davon effizienter ist, hängt weitgehend vom Linq-Provider ab, den Sie verwenden. Mein Geld ist zuletzt sortiert. Obwohl ich denke, dass der Anbieter schlau genug ist, die Operationen in der besten Reihenfolge zu bestellen. Vielleicht möchten Sie das überprüfen.