Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq - Question concerning the 'Any' method

Tags:

linq

Assume I have the following query against the AdventureWorks DB:

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

This query will return all customers who live in Dallas. However, I'm not sure why it works. I know the 'Any' method returns a Boolean depending on whether any of the rows in the sequence satisfy the predicate. But used in this way, it appears it's actually returning a sequence of rows that do satisfy the predicate. I guess I'm not sure exactly what's happening here.

However, used in the following way, it's easy to understand how 'Any' is working:

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

This returns false because no customers live in Largo.

like image 926
Randy Minder Avatar asked Jun 16 '11 11:06

Randy Minder


3 Answers

The first query can be read as

Return all customers who have any addresses in Dallas.

The response or result in the query is "here are those customers." The first query, the Any is strictly against the addresses. So customers that have addresses that satisfy the Any are returned.

The second query as

Do I have any customers who have any addresses in Largo?

The result is either yes or no (true or false). You have applied the Any to both the addresses and and the results of the Any on addresses. So the first part of the query is "filter by customers with addresses in Largo" and the second is "now all I want to know is if I have any such customers."

Does it make sense now?

like image 117
Anthony Pegram Avatar answered Oct 13 '22 09:10

Anthony Pegram


Any returns a bool, but it's being fed to the where clause. The where clause takes a boolean expression, applies it to each item in a sequence, and returns those items where the expression is true. So in the extension method syntax, your query translates to:

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

Your second example is almost exactly the same, except that it uses an outer Any in place of the Where. Here it is, formatted to match the code above:

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

Simplifying further, it becomes even more clear what's happening:

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

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

We see that the Where clause is what's really driving your first query. You could write it in English as:

Give me all the customers who have at least one address in Dallas. Ignore their other addresses. If a customer has no addresses in Dallas, filter him/her out of the results.

As you can see, this is asking for a list of customers. The second one works out to:

Is there at least one customer who has at least one address in Dallas?

This is a yes/no question, so it returns true or false.

like image 25
Justin Morgan Avatar answered Oct 13 '22 11:10

Justin Morgan


You are getting a list of rows that do satisfy the predicate because you are using the Any method as a where clause to a select statement, which will select a list of rows.

So your first example says 'select all customers who have an address where the address' city is equal to Dallas'. Any isn't returning a list of rows (it is just acting as a condition to the where clause), the select statement is.

like image 28
mdm Avatar answered Oct 13 '22 09:10

mdm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!