简体   繁体   中英

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();

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.

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.

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 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM