J'écris pas mal de linq dans ma vie de tous les jours, mais surtout des déclarations simples. J'ai remarqué que lors de l'utilisation de clauses where, il existe de nombreuses façons de les écrire et chacune a les mêmes résultats pour autant que je sache. Par exemple;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
Cela semble équivalent au moins en ce qui concerne les résultats:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
Alors, y a-t-il vraiment une différence autre que la syntaxe? Si oui, quel est le style préféré et pourquoi?
Fat
propriété booléenne ? C'est tout simplement méchant.Réponses:
Le second serait plus efficace car il n'a qu'un seul prédicat à évaluer par rapport à chaque élément de la collection où, comme dans le premier, il applique le premier prédicat à tous les éléments en premier et le résultat (qui est réduit à ce stade) est utilisé pour le deuxième prédicat et ainsi de suite. Les résultats sont réduits à chaque passage, mais cela implique toujours plusieurs passes.
De plus, le chaînage (première méthode) ne fonctionnera que si vous effectuez un ET vos prédicats. Quelque chose comme ça
x.Age == 10 || x.Fat == true
ne fonctionnera pas avec votre première méthode.la source
EDIT: LINQ to Objects ne se comporte pas comme je m'y attendais. Vous serez peut-être intéressé par le billet de blog que je viens d'écrire à ce sujet ...
Ils sont différents en termes de ce que l'on appellera - le premier équivaut à:
où ce dernier équivaut à:
Maintenant , quelle différence cela fait en fait dépend de la mise en œuvre d'
Where
être appelé. S'il s'agit d'un fournisseur basé sur SQL, je m'attendrais à ce que les deux finissent par créer le même SQL. Si c'est dans LINQ to Objects, le second aura moins de niveaux d'indirection (il n'y aura que deux itérateurs impliqués au lieu de quatre). La question de savoir si ces niveaux d'indirection sont significatifs en termes de vitesse est une autre question.En règle générale, j'utiliserais plusieurs
where
clauses si elles avaient l'impression de représenter des conditions significativement différentes (par exemple, l'une estwhere
liée à une partie d'un objet et l'autre est complètement séparée) et une clause lorsque diverses conditions sont étroitement liées (par exemple, une valeur particulière est supérieur à un minimum et inférieur à un maximum). En gros, il vaut la peine de considérer la lisibilité avant toute légère différence de performance.la source
Le premier sera mis en œuvre:
Par opposition au beaucoup plus simple (et
beaucoup plus rapideprobablement plus rapide):la source
quand je cours
et
contre ma table client, il génère la même requête SQL
donc dans la traduction en sql il n'y a pas de différence et vous avez déjà vu dans d'autres réponses comment elles seront converties en expressions lambda
la source
En regardant sous le capot, les deux instructions seront transformées en différentes représentations de requête. Selon le
QueryProvider
deCollection
, cela peut être optimisé ou non.Lorsqu'il s'agit d'un appel linq-to-object, plusieurs clauses where mèneront à une chaîne de IEnumerables qui se lisent les uns les autres. L'utilisation du formulaire à clause unique améliorera les performances ici.
Lorsque le fournisseur sous-jacent le traduit en une instruction SQL, les chances sont bonnes que les deux variantes créent la même instruction.
la source