2011-11-15 19 views
8

Hoy me encontré con un problema con LINQ para objetos (no SQL) que aparecieron debido a un error tipográfico. Tenía un lugar .Select y un .Where en otro lugar. Esperaba el mismo resultado, pero muestran números diferentes. Asumir somelist tiene 10 elementos con todos los elementos que tienen qty = 0linq ambigüedad en donde y seleccione

//returns 10 - basically count of all rows. I am expecting 0 
somelist.Select(p => p.qty > 0).Count() 

//returns 0 - the correct count 
somelist.Where(p => p.qty > 0).Count() 

si ambos seleccionan y donde volver IEnumerable<T> entonces ¿por qué la ambigüedad? Gracias.

+0

thx everyone para esa actualización de linq 101. – Gullu

+0

Es uno de esos problemas de nombres interesantes, C# trata de ser sintácticamente como sql (que sql sugiere seleccionar columnas), pero el nombre 'Seleccionar', especialmente si ingresas un predicado, puede leer como tú para seleccionar solo dicho los artículos que pasan, de hecho en ruby ​​y smalltalk eso es lo que hace el método 'select '. – jbtule

Respuesta

18

Select es una proyección, entonces lo que obtienes es la expresión p.qty > 0 evaluada para cada elemento en somelist. es decir, muchos valores verdadero/falso (el mismo número que su lista original). Entonces cuando haces Count en él, obtienes el mismo número. Si mira, seleccionar devolverá IEnumerable<bool> (porque el tipo de p.qty > 0 es un bool).

Where filtra los resultados para que el recuento se ejecute en la lista filtrada y le brinde los resultados esperados. El tipo de esto es un IEnumerable<TypeOfElementInOriginalList>.

Tenga en cuenta que también puede hacer: somelist.Count(p => p.qty > 0) porque Count tiene un overload que acepta un predicado para filtrar.

2

La primera consulta da lo mismo que somelist.Count(). Es solo el número de elementos en la secuencia. La llamada a Selectproyecta cada objeto, pero la cantidad de objetos sigue siendo la misma.

La segunda consulta proporciona la cantidad de elementos que cumplen el predicado, que es un número potencialmente menor. La llamada a Wherefiltra objetos de la secuencia.

0

La primera consulta devuelve un IEnumerable de booleanos.

La segunda consulta solo devuelve elementos en el original que coinciden con la expresión booleana.

0

La primera instrucción crea un IEnumerable de bools: es el campo qty> 0. Como hay 10 registros, obtienes 10 bools.

El segundo devuelve un IEnumerable filtrado sobre la condición.