Dewasish Mitruka
Dewasish Mitruka

Reputation: 2896

What is the different between the following two query of LINQ

I did not understood the difference between the following query and at what condition which query should used :

 var productGroups = 
        from p in products 
        group p by p.Category into g 
        where g.Any(p => p.UnitsInStock == 0) 
        select new { Category = g.Key, Products = g }; 



var productGroups = 
        from p in products 
        group p by p.Category into g 
        where g.Where(p => p.UnitsInStock == 0) 
        select new { Category = g.Key, Products = g }; 

Upvotes: 1

Views: 87

Answers (1)

Anthony Pegram
Anthony Pegram

Reputation: 126794

The difference is the second is not legal code and will not compile.

where g.Where(...) 

g.Where is itself a filtering operation. It yields a sequence of whatever type g happens to be. It does not yield a boolean, which is what is needed to use it as a predicate in another where expression.

On the other hand, g.Any(...) is a method that returns boolean, which allows you to use it in a where clause of the query.

The first query (the legal one) groups your products by category, and then filters to select the groups that have a product with 0 units in stock. As long as any product in the category has 0 units in stock, the group is selected into an anonymous type comprising the Category and then the products in that category.

If you have

var products = new List<Product> 
{
    new Product { Category = "Widgets", Name = "Foo", UnitsInStock = 14 },
    new Product { Category = "Widgets", Name = "Bar", UnitsInStock = 0 },
    new Product { Category = "Frobbers", Name = "Baz", UnitsInStock = 32 },
    new Product { Category = "Frobbers", Name = "Blah", UnitsInStock = 9 }
};

Then Widgets will pass your predicate because it has a product with 0 units. Frobbers will be filtered out.

The second query can be fixed to perform the same function as the first by simply applying the Any method following the Where.

 where g.Where(p => p.UnitsInStock == 0).Any()

There is no difference, then, in output, as the predicates are the same. The difference is simply where the predicate is specified. In the first query, it uses the overload of Any that accepts a predicate, the second (once fixed) uses the overload with no predicate but after the predicate has been applied via a Where method. Both approaches lazily stream the elements through the methods, evaluating only as much as necessary in order to validate the condition. It is therefore mostly up to you which version to use, and I would simply opt for the version of Any that accepts a predicate.

Upvotes: 4

Related Questions