query - linq c# tutorial español
Linq apropiado donde cláusulas (5)
EDITAR: LINQ to Objects no se comporta como esperaba. Puede que le interese la publicación del blog que acabo de escribir sobre esto ...
Son diferentes en términos de lo que se llamará: el primero es equivalente a:
Collection.Where(x => x.Age == 10)
.Where(x => x.Name == "Fido")
.Where(x => x.Fat == true)
cuando el último es equivalente a:
Collection.Where(x => x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true)
Ahora, la diferencia que realmente hace depende de la implementación de Where
se llama. Si se trata de un proveedor basado en SQL, espero que los dos terminen creando el mismo SQL. Si está en LINQ to Objects, el segundo tendrá menos niveles de indirección (habrá solo dos iteradores involucrados en lugar de cuatro). Si esos niveles de direccionamiento indirecto son significativos en términos de velocidad es una cuestión diferente.
Por lo general, utilizaría varias cláusulas where
si sienten que representan condiciones significativamente diferentes (por ejemplo, una tiene que ver con una parte de un objeto, y una está completamente separada) y una cláusula where
cuando varias condiciones están estrechamente relacionadas (por ejemplo, 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 pequeña diferencia de rendimiento.
Escribo una buena cantidad de linq en mi vida cotidiana, pero en su mayoría declaraciones simples. Me he dado cuenta de que al usar las cláusulas where, hay muchas formas de escribirlas y cada una tiene los mismos resultados 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é?
El primero se implementará:
Collection.Where(x => x.Age == 10)
.Where(x => x.Name == "Fido") // applied to the result of the previous
.Where(x => x.Fat == true) // applied to the result of the previous
A diferencia de lo mucho más simple (y mucho más rápido, presumiblemente más rápido):
// all in one fell swoop
Collection.Where(x => x.Age == 10 && x.Name == "Fido" && x.Fat == true)
El segundo sería más eficiente ya que solo tiene un predicado para evaluar contra cada elemento en la colección donde, como en el primero, aplica primero el primer predicado a todos los elementos y el resultado (que se reduce en este punto) es utilizado para el segundo predicado y así sucesivamente. Los resultados se reducen en cada pasada, pero aún así implica múltiples pases.
También el encadenamiento (primer método) funcionará solo si está ANDing sus predicados. Algo así x.Age == 10 || x.Fat == true
x.Age == 10 || x.Fat == true
no funcionará con su primer método.
Mirando debajo del capó, las dos declaraciones se transformarán en diferentes representaciones de consulta. Dependiendo del QueryProvider
of Collection
, esto podría optimizarse o no.
Cuando se trata de una llamada de linq a objeto, varias cláusulas where conducirán a una cadena de IEnumerables que se leen entre sí. Usar el formulario de cláusula única ayudará a mejorar el rendimiento aquí.
Cuando el proveedor subyacente lo traduce en una declaración SQL, es probable que ambas variantes creen la misma declaración.
cuando corro
from c in Customers
where c.CustomerID == 1
where c.CustomerID == 2
where c.CustomerID == 3
select c
y
from c in Customers
where c.CustomerID == 1 &&
c.CustomerID == 2 &&
c.CustomerID == 3
select c customer table in linqpad
contra mi tabla de clientes da como resultado la misma consulta sql
-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 Int = 2
DECLARE @p2 Int = 3
-- EndRegion
SELECT [t0].[CustomerID], [t0].[CustomerName]
FROM [Customers] AS [t0]
WHERE ([t0].[CustomerID] = @p0) AND ([t0].[CustomerID] = @p1) AND ([t0].[CustomerID] = @p2)
entonces en traducción a sql no hay diferencia y ya has visto en otras respuestas cómo se convertirán a expresiones lambda