Ich versuche, einen LINQ-Provider zu erstellen. Ich verwende den Leitfaden LINQ: Erstellen einer IQueryable-Anbieterserie , und ich habe den Code bis LINQ hinzugefügt: Erstellen eines IQueryable Provider - Teil IV.
Ich habe ein Gefühl dafür, wie es funktioniert und welche Idee dahinter steckt. Jetzt stecke ich an einem Problem, das kein Code-Problem ist, sondern mehr über das Verständnis.
Ich feuere diese Aussage ab:
%Vor% Irgendwie weiß der Code oder Ausdruck, dass das Where
vor dem Select
steht. Aber wie und wo?
Es gibt keine Möglichkeit, den Ausdruck im Code zu sortieren. Tatsächlich zeigt das ToString()
im Debug-Modus, dass das Select vor dem Where
steht.
Ich habe versucht, den Code zum Scheitern zu bringen. Normal habe ich zuerst Where
und dann Select
gemacht.
Wie sortiert der Ausdruck das? Ich habe keine Änderungen am Code im Leitfaden vorgenommen.
Die Ausdrücke werden in der Reihenfolge "interpretiert", "übersetzt" oder "ausgeführt", in der Sie sie schreiben - also kommt %%_Code% nicht vor %%_CODE%
Wenn Sie Folgendes ausführen:
%Vor% Dann wird das Where
auf dem Select
oder Where
des anonymen Typs ausgeführt.
Wenn Sie Folgendes ausführen:
%Vor% Dann wird das IEnumerable
auf dem IQueryable
oder Where
des Kundentyps ausgeführt.
Das Einzige, was mir einfällt, ist, dass Sie vielleicht etwas generiertes SQL sehen, wo SELECT und WHERE neu geordnet wurden? In diesem Fall würde ich vermuten, dass es irgendwo im (zB) LINQ to SQL Provider einen Optimierungsschritt gibt IEnumerable
und konvertiert es in IQueryable
- aber dies muss eine providerspezifische Optimierung sein.
Nein, im allgemeinen Fall (wie zum Beispiel LINQ to Objects ) wird die Auswahl vor dem Where ausgeführt Erklärung. Denken Sie daran, es ist eine Pipeline, Ihr erster Schritt ist eine Transformation, der zweite ein Filter. Nicht umgekehrt, wie es der Fall wäre, wenn Sie Where ... Select schreiben würden.
Nun hat ein LINQ-Provider die Freiheit, den Ausdrucksbaum zu gehen und ihn so zu optimieren, wie er es für richtig hält. Beachten Sie jedoch, dass Sie die Semantik des Ausdrucks nicht ändern können. Dies bedeutet, dass ein intelligenter LINQ to SQL -Anbieter versuchen würde, so viele where
-Klauseln in das SQL zu ziehen Abfrage, um die Menge an Daten zu reduzieren, die über das Netzwerk übertragen werden. Behalten Sie jedoch das Beispiel von Stuart im Hinterkopf: Nicht alle Abfrageanbieter sind clever, auch weil der Ausschluss von Seiteneffekten aus der Nachbestellung von Abfragen nicht so einfach ist, wie es scheint.