2010-09-13 8 views
48

Desafortunadamente, los nombres de estos métodos hacen terribles términos de búsqueda, y no he podido encontrar un buen recurso que explique la diferencia entre estos métodos- -como en cuándo usar cada uno.Métodos de extensión LINQ - Cualquiera() frente a Where() versus Exists()

Gracias.

Editar:

El tipo de consulta que estoy tratando de entender completamente es algo como esto:

context.Authors.Where(a => a.Books.Any(b => b.BookID == bookID)).ToList(); 

Y gracias a todos los que he respondido.

+6

También recomendaría [101 muestras LINQ] (http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx). – Kobi

+0

Pregunta similar aquí: http://stackoverflow.com/questions/879391/linq-any-vs-exists-whats-the-difference –

Respuesta

81

Where devuelve una nueva secuencia de elementos que coinciden con el predicado.

Any devuelve un valor booleano; hay una versión con un predicado (en cuyo caso devuelve si los elementos coinciden o no) y una versión sin (en cuyo caso se devuelve si la consulta hasta ahora contiene algún elemento). No estoy seguro de Exists - No es un operador de consulta estándar LINQ. Si hay una versión para Entity Framework, tal vez verifique su existencia en función de una clave, ¿es una especie de forma especializada de Any? (Hay un método Exists en List<T> que es similar a Any(predicate) sino que es anterior a LINQ.)

+2

EXISTS - http://msdn.microsoft.com/en-us/library/bfed8bca .aspx – JonH

+8

@JonH: Sí, como publiqué, es parte de 'List ' - que no forma parte de LINQ. –

+0

Pero en la función, '.Any' y' .Exists' son exactamente iguales. – Flater

7

Sólo para que pueda encontrar la próxima vez, aquí es cómo usted busca para las extensiones de Linq enumerables. Los métodos son métodos estáticos de Enumerable, por lo tanto Enumerable.Any, Enumerable.Where y Enumerable.Exists.

A medida que los terceros no devuelve ningún resultado útil, me pareció que significaba List.Exists, así:

También recomiendo hookedonlinq.com ya que este tiene guías muy completas y claras, así como explicaciones claras del comportamiento de los métodos de Linq en relación con diferimiento y pereza.

+0

Gracias por los enlaces. Busqué "ienumerable <>. Any()", que estaba cerca, supongo, pero inútil. – asfsadf

0

Cualquiera() devuelve verdadero si alguno de los elementos de una colección cumple los criterios de su predicado.

Where() devuelve un enumerable de todos los elementos de una colección que cumplen los criterios de su predicado.

Exists() hace lo mismo que cualquiera excepto que es solo una implementación anterior que estaba allí en el IList antes de Linq.

+5

No en IList: solo 'Lista ' –

3

Cualquiera - función booleana que devuelve verdadero cuando cualquiera de los objetos en la lista cumple la condición establecida en los parámetros de la función.Por ejemplo:

List<string> strings = LoadList(); 
boolean hasNonEmptyObject = strings.Any(s=>string.IsNullOrEmpty(s)); 

Where - función que devuelve la lista con todos los objetos de la lista que satisfacen las condiciones establecidas en los parámetros de la función. Por ejemplo:

IEnumerable<string> nonEmptyStrings = strings.Where(s=> !string.IsNullOrEmpty(s)); 

Exists - básicamente el mismo que cualquier pero no es genérica - se define en la clase de lista, mientras que cualquier se define en la interfaz IEnumerable.

+2

Su segundo ejemplo no se compilará, ya que Where devuelve 'IEnumerable '. –

+0

Sí, gracias. Arreglado. –

1

IEnumerable presenta un buen número de extensiones, lo que le ayuda a pasar su propio delegado e invocar el resultado desde la parte posterior de IEnumerable. La mayoría de ellos son por naturaleza del tipo Func

El Func toma un argumento T y devuelve TResult.

En caso de

Dónde - Func: Así que toma IEnumerable de T y devuelve un bool. El where finalmente devolverá el IEnumerable de T para el cual Func devuelve verdadero.

Así que si tiene 1,5,3,6,7 como IEnumerable y escribe .where (r => r < 5) devolverá un nuevo IEnumerable de 1,3.

Any - Func básicamente es similar en la firma pero devuelve verdadero solo cuando cualquiera de los criterios devuelve verdadero para IEnumerable. En nuestro caso, devolverá verdadero ya que hay pocos elementos presentes con r < 5.

Existe - El predicado por el contrario solo devuelve verdadero cuando cualquiera de los predicados devuelve verdadero. Por lo tanto, en nuestro caso, si aprueba .Exists (r => 5) devolverá true ya que 5 es un elemento presente en IEnumerable.

9

context.Authors.Where (a => a.Books.Any (b => b.BookID == BookID)) ToList().;

a.Books es la lista de libros de ese autor. La propiedad se crea automáticamente por Linq-to-Sql, siempre que tenga una configuración de relación de clave externa.

Por lo tanto, a.Books.Any(b => b.BookID == bookID) se traduce como "¿Alguno de los libros de este autor tiene una ID de bookID", que hace la expresión completa "¿Quiénes son los autores del libro con idIDIDID?"

Eso también se podría escribir algo así como

from a in context.Authors 
    join b in context.Books on a.AuthorId equal b.AuthorID 
    where b.BookID == bookID 
    select a; 

ACTUALIZACIÓN: Any() por lo que yo sé, sólo se devuelve un bool. Su aplicación efectiva es:

public Any(this IEnumerable<T> coll, Func<T, bool> predicate) 
{ 
    foreach(T t in coll) 
    { 
     if (predicte(t)) 
      return true; 
    } 
    return false; 
} 
+0

Creo que la parte que me está arrojando es cómo Any() devuelve un bool, lo que significa que estoy leyendo "sí, el autor tiene un libro en su colección que tiene este ID de libro". ¿Su otra sobrecarga de Any() devuelve algo diferente? – asfsadf

+0

Sí, esta es la razón por la que estoy confundido. La forma en que el método Any() está encadenado no tiene sentido para mí. No devuelve un libro, sino un bool. Hombre vivo estoy en el mar en este. Tal vez solo necesito otra taza de café. Gracias por todo el esfuerzo, por cierto. – asfsadf

+2

No veo el problema. Any() devuelve un bool, Where() espera un bool. ¡Todos están felices! –

Cuestiones relacionadas