Reputation: 385
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
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
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
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