Escribo una buena cantidad de linq en mi día a día, pero sobre todo declaraciones simples. Me he dado cuenta de que cuando utilizo las cláusulas where, hay muchas maneras de escribirlas y cada una tiene los mismos resultados por lo que puedo decir. Por ejemplo;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
Parece ser equivalente a esto al menos en lo que respecta a los resultados:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
Entonces, ¿hay realmente una diferencia que no sea la sintaxis? Si es así, ¿cuál es el estilo preferido y por qué?
Fat
propiedad booleana ? Eso es muy malo.Respuestas:
El segundo sería más eficiente, ya que solo tiene un predicado para evaluar contra cada elemento de la colección donde, como en el primero, está aplicando el primer predicado a todos los elementos primero y el resultado (que se reduce en este punto) es usado para el segundo predicado y así sucesivamente. Los resultados se reducen en cada pasada, pero aún implica varias pasadas.
Además, el encadenamiento (primer método) funcionará solo si está ANDinging sus predicados. Algo como esto
x.Age == 10 || x.Fat == true
no funcionará con su primer método.fuente
EDITAR: LINQ to Objects no se comporta como esperaba. Puede que te interese la publicación de blog que acabo de escribir sobre esto ...
Son diferentes en términos de lo que se llamará: el primero es equivalente a:
donde este último es equivalente a:
Ahora, la diferencia que realmente hace depende de la implementación de
Where
ser llamado. Si se trata de un proveedor basado en SQL, esperaría que ambos terminen creando el mismo SQL. Si está en LINQ to Objects, el segundo tendrá menos niveles de indirección (solo habrá dos iteradores involucrados en lugar de cuatro). Si esos niveles de indirección son significativos en términos de velocidad es una cuestión diferente.Por lo general, usaría varias
where
cláusulas si consideran que representan condiciones significativamente diferentes (por ejemplo, una tiene que ver con una parte de un objeto y otra está completamente separada) y unawhere
cláusula cuando varias condiciones están estrechamente relacionadas (por ejemplo, un valor particular es mayor que un mínimo y menor que un máximo). Básicamente vale la pena considerar la legibilidad antes de cualquier ligera diferencia de rendimiento.fuente
El primero se implementará:
A diferencia de lo mucho más simple (y
mucho más rápido,presumiblemente más rápido):fuente
cuando corro
y
contra mi tabla de Clientes, genera la misma consulta SQL
así que en la traducción a sql no hay diferencia y ya has visto en otras respuestas cómo se convertirán a expresiones lambda
fuente
Mirando debajo del capó, las dos declaraciones se transformarán en diferentes representaciones de consulta. Dependiendo
QueryProvider
deCollection
esto, esto podría optimizarse o no.Cuando se trata de una llamada de linq a objeto, las cláusulas where múltiples conducirán a una cadena de IEnumerables que se leerán entre sí. Usar el formulario de una sola cláusula ayudará al rendimiento aquí.
Cuando el proveedor subyacente lo traduce a una declaración SQL, hay muchas posibilidades de que ambas variantes creen la misma declaración.
fuente