2011-06-16 12 views
6

Supongamos que tengo la siguiente consulta en la base de datos AdventureWorks:LINQ - Cuestión relativa a la 'Cualquier' método

var result = from customer in Customer 
    where customer.CustomerAddress.Any (ca => ca.Address.City == "Dallas") 
    select new 
    { 
     customer.Individual.Contact.FirstName, 
     Addresses = customer.CustomerAddress 
    }; 

Esta consulta devolverá todos los clientes que viven en Dallas. Sin embargo, no estoy seguro de por qué funciona. Sé que el método 'Cualquiera' devuelve un Booleano dependiendo de si alguna de las filas en la secuencia satisface el predicado. Pero utilizado de esta manera, parece que en realidad está devolviendo una secuencia de filas que sí satisfacen el predicado. Supongo que no estoy seguro de qué está pasando exactamente aquí.

Sin embargo, se usa de la siguiente manera, es fácil entender cómo 'Cualquier' está funcionando:

var result = Customer.Any (c => c.CustomerAddress.Any (ca => ca.Address.City == "Largo")); 

Esto devuelve falso, porque no hay clientes viven en Largo.

+0

¿Cuál es el punto que no entiendes? ¿Es el primer ejemplo que devuelve filas y el segundo booleano? – archil

+0

@archil - Sí, exactamente. –

Respuesta

11

La primera consulta se puede leer como

Volver a todos los clientes que tienen alguna direcciones en Dallas.

La respuesta o resultado en la consulta es "aquí están esos clientes". La primera consulta, Any es estrictamente contra las direcciones. Por lo tanto, se devuelven los clientes que tienen direcciones que satisfacen el Any.

La segunda consulta como

¿Tengo clientes que tienen alguna direcciones en Largo?

El resultado es sí o no (verdadero o falso). Ha aplicado Any a las direcciones y y los resultados de Any en las direcciones. De modo que la primera parte de la consulta es "filtrada por clientes con direcciones en Largo" y la segunda es "ahora todo lo que quiero saber es si tengo tales clientes".

¿Tiene sentido ahora?

1

Obtiene una lista de filas que satisfacen el predicado porque está utilizando el método Any como cláusula where en una instrucción select, que seleccionará una lista de filas.

Por lo tanto, su primer ejemplo dice 'seleccionar todos los clientes que tengan una dirección donde la dirección' ciudad es igual a Dallas '. Any no devuelve una lista de filas (solo está actuando como una condición para la cláusula where), la instrucción select es.

1

donde se evalúa la declaración para cada elemento en el cliente (un sí o no sobre cada cliente). Por lo tanto, recibirá a todos los clientes que tengan Cualquier dirección ciudad = Dallas.

La segunda declaración dice específicamente si un cliente tiene una dirección de ciudad = Largo.(Sí o no)

1
  • Para cada customer en Customer
  • Cuando la colección de CustomerAddresses de customer tiene al menos un Address con un campo City que coincide con "Dallas"
  • Seleccionar "El primer nombre y la colección de direcciones del cliente".
1

Acá ambos de sus ejemplos reescritos en la sintaxis de método (primera es en la sintaxis de mezclado en su ejemplo, segundos ya está en método)

IEnumerable result = Customers 
    .Where(c => c.CustomerAddress.Any(ca => ca.Address.City == "Dallas")) 
    .Select(c=> new { FirstName = c.Individual.Contact.FirstName, Addresses = c.Addresses}; 

    //vs 

    bool result = Customers.Any (c => c.CustomerAddress.Any (ca => ca.Address.City == "Dallas")); 

Ver las asignaciones? La primera instrucción finaliza con Select => returns enumerable. El segundo extremo con Cualquiera => devuelve bool

4

Any devuelve un bool, pero se está alimentando a la cláusula where. La cláusula where toma una expresión booleana, la aplica a cada elemento en una secuencia y devuelve aquellos elementos donde la expresión es verdadera. Así que en la sintaxis método de extensión, la consulta se traduce en:

var result = Customer 
      .Where(customer => customer.CustomerAddress.Any(ca => ca.Address.City == "Dallas")) 
      .Select(customer => new { /*...*/ }); 

Su segundo ejemplo es casi exactamente el mismo, excepto que utiliza una combinación externa Any en lugar de la Where. Aquí está, el formato para que coincida con el código anterior:

var result = Customer 
      .Any(c => c.CustomerAddress.Any(ca => ca.Address.City == "Largo")); 

simplificando aún más, se vuelve aún más claro lo que está pasando:

var result1 = Customer 
       .Where(customer => customer.HasAnyAddressHere); 

var result2 = Customer 
       .Any(customer => customer.HasAnyAddressHere); 

vemos que la cláusula Where es lo que realmente mueve a su primera consulta. Puede escribirlo en inglés como:

Dame a todos los clientes que tienen al menos una dirección en Dallas. Ignora sus otras direcciones. Si un cliente no tiene direcciones en Dallas, filtrarlo de los resultados.

Como puede ver, esto es pedir una lista de clientes. El segundo funciona a:

¿Hay al menos un cliente que tenga al menos una dirección en Dallas?

Esta es una pregunta sí/no, por lo que devuelve verdadero o falso.

Cuestiones relacionadas