Ich schreibe in meinem täglichen Leben eine ganze Menge Linq, aber meistens einfache Aussagen. Ich habe festgestellt, dass es bei der Verwendung von where-Klauseln viele Möglichkeiten gibt, sie zu schreiben, und jede hat, soweit ich das beurteilen kann, die gleichen Ergebnisse. Beispielsweise;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
Scheint zumindest in Bezug auf die Ergebnisse gleichwertig zu sein:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
Gibt es also wirklich einen anderen Unterschied als die Syntax? Wenn ja, welcher Stil wird bevorzugt und warum?
Fat
Eigenschaft? Das ist einfach gemein.Antworten:
Das zweite ist effizienter, da nur ein Prädikat für jedes Element in der Sammlung ausgewertet werden muss, wobei wie im ersten das erste Prädikat zuerst auf alle Elemente angewendet wird und das Ergebnis (das an dieser Stelle eingegrenzt wird) ist wird für das zweite Prädikat verwendet und so weiter. Die Ergebnisse werden bei jedem Durchgang eingegrenzt, es handelt sich jedoch immer noch um mehrere Durchgänge.
Auch die Verkettung (erste Methode) funktioniert nur, wenn Sie Ihre Prädikate UND-verknüpfen. So etwas
x.Age == 10 || x.Fat == true
funktioniert mit Ihrer ersten Methode nicht.quelle
EDIT: LINQ to Objects verhält sich nicht so, wie ich es erwartet hatte. Vielleicht interessiert Sie auch der Blog-Beitrag, den ich gerade darüber geschrieben habe ...
Sie unterscheiden sich in Bezug auf das, was genannt wird - das erste entspricht:
wobei letzteres äquivalent ist zu:
Welcher Unterschied das tatsächlich macht, hängt von der Implementierung des
Where
Aufrufs ab. Wenn es sich um einen SQL-basierten Anbieter handelt, würde ich erwarten, dass die beiden am Ende dasselbe SQL erstellen. Wenn es sich um LINQ to Objects handelt, weist die zweite weniger Indirektionsebenen auf (es sind nur zwei statt vier Iteratoren beteiligt). Ob diese Dereferenzierungsebenen sind signifikant in Bezug auf die Geschwindigkeit ist eine andere Sache.Normalerweise würde ich mehrere
where
Klauseln verwenden, wenn sie das Gefühl haben, signifikant unterschiedliche Bedingungen darzustellen (z. B. eine betrifft einen Teil eines Objekts und eine ist vollständig getrennt), und einewhere
Klausel, wenn verschiedene Bedingungen eng miteinander verbunden sind (z. B. einen bestimmten Wert) ist größer als ein Minimum und kleiner als ein Maximum). Grundsätzlich lohnt es sich, die Lesbarkeit zu berücksichtigen, bevor geringfügige Leistungsunterschiede auftreten.quelle
Der erste wird implementiert:
Im Gegensatz zu den viel einfacheren (und
weitaus schnellerenvermutlich schneller):quelle
wenn ich renne
und
Für meine Kundentabelle wird dieselbe SQL-Abfrage ausgegeben
Bei der Übersetzung in SQL gibt es also keinen Unterschied, und Sie haben bereits in anderen Antworten gesehen, wie sie in Lambda-Ausdrücke konvertiert werden
quelle
Unter der Haube werden die beiden Anweisungen in unterschiedliche Abfragedarstellungen umgewandelt. Je nach
QueryProvider
demCollection
, könnte dies wegoptimiert oder nicht.Wenn es sich um einen Linq-to-Object-Aufruf handelt, führen mehrere where-Klauseln zu einer Kette von IEnumerables, die voneinander lesen. Die Verwendung des Einzelklauselformulars trägt hier zur Leistungssteigerung bei.
Wenn der zugrunde liegende Anbieter es in eine SQL-Anweisung übersetzt, stehen die Chancen gut, dass beide Varianten dieselbe Anweisung erstellen.
quelle