user350213
user350213

Reputation: 385

What is the difference between these 2 LINQ queries?

I have 2 LINQ queries, one returns what I expect, the other doesn't and i'm trying to understand why. I'm trying to figure out if from all the nodes in Config, is there a node that is called "TEST" and its Selected attribute is True.

Query 1 - Which returns the right thing has the condition inside Any():

var res1 =
(from config in _config.CurrentSettings.Config let name = config.name select config).Any(
    config => config.name.Equals("TEST") && config.selected == true);

Query 2, which fails, has the condition inside Select:

(_config.CurrentSettings.Config.Select(config => config.name.Equals("TEST") && config.selected))
.Any();

Upvotes: 3

Views: 101

Answers (3)

Garrett Clyde
Garrett Clyde

Reputation: 306

You may want to try:

var isTestSelected = _config.CurrentSettings.Config.Any(config => config.name.Equals("TEST") && config.selected);

Looking at the documentation for the Select and Any methods, may provide some insight.

If you look at the Parameters section of each of those links, you'll see that while both methods accept a Func, their usage is actually different.

Any

predicate Type: System.Func<TSource, Boolean> A function to test each element for a condition.

Select

selector Type: System.Func<TSource, TResult> A transform function to apply to each element.

So, in your Query1 example, you're applying a transform (or map) to each item in your collection, which declares a local name variable let name = config.name (which is not being used), and then just returns the object as is (without actually transforming anything) select config. This bit of code is superfluous, and can be removed.

Your Any() lambda is doing all the work in Query1, by filtering items that don't match your lambda predicate.

In Query2, you're passing a filtering lambda to a transform function, and then using a filtering function without a filter.

There are many different ways to get your desired result using Linq. I encourage you to look at the different mapping (selector) and filtering (predicate) functions provided by the framework (link).

Upvotes: 1

M.kazem Akhgary
M.kazem Akhgary

Reputation: 19179

The whole thing here is useless.

(from config in _config.CurrentSettings.Config let name = config.name select config)

You can narrow it down to this

_config.CurrentSettings.Config.Any(config => config.name.Equals("TEST") && config.selected == true);

Which will perform same as your first block of code.

The Select methods converts an ienumerable into another form using a selector you give. parameter-less Any returns true if sequence contains any element. otherwise returns false.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

LINQ's Any() with no condition means "has at least one row". The first query specifies a condition, making it "has at least one row matching the condition".

To make the second query equivalent to first one, use Any(flag => flag), or replace Select with Where. Both these options are inferior to the initial Any, with the condition inside, because they are not as readable.

Upvotes: 5

Related Questions