简体   繁体   English

这两个LINQ查询有什么区别?

[英]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. 我有2个LINQ查询,一个返回我期望的,另一个没有,我试图理解为什么。 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. 我试图找出是否从Config中的所有节点,是否有一个名为“TEST”的节点,其Selected属性为True。

Query 1 - Which returns the right thing has the condition inside Any(): 查询1 - 返回正确的东西的条件是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: 失败的查询2具有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". LINQ的Any()没有条件意味着“至少有一行”。 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 . 要使第二个查询等效于第一个查询,请使用Any(flag => flag) ,或将Select替换为Where Both these options are inferior to the initial Any , with the condition inside, because they are not as readable. 这两个选项都不如初始的Any ,条件在里面,因为它们不具有可读性。

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. Select方法使用您提供的选择器将不可数据转换为另一个表单。 parameter-less Any returns true if sequence contains any element. 无参数的Any如果序列中包含的任何元素返回true。 otherwise returns false. 否则返回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. 查看SelectAny方法的文档,可能会提供一些见解。

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. 如果查看每个链接的“参数”部分,您会看到虽然两个方法都接受Func ,但它们的用法实际上是不同的。

Any 任何

predicate Type: System.Func<TSource, Boolean> A function to test each element for a condition. predicate类型: System.Func<TSource, Boolean>用于测试条件的每个元素的函数。

Select 选择

selector Type: System.Func<TSource, TResult> A transform function to apply to each element. selector类型: System.Func<TSource, TResult>要应用于每个元素的转换函数。

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 . 因此,在Query1示例中,您将一个转换(或映射)应用于集合中的每个项目,它声明一个本地名称变量let name = config.name (未使用),然后只返回该对象原样(没有实际转换任何东西) 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. 你的Any() lambda通过过滤与lambda谓词不匹配的项来完成Query1中的所有工作。

In Query2, you're passing a filtering lambda to a transform function, and then using a filtering function without a filter. 在Query2中,您将过滤lambda传递给变换函数,然后使用不带过滤器的过滤函数。

There are many different ways to get your desired result using Linq. 使用Linq有许多不同的方法可以获得所需的结果。 I encourage you to look at the different mapping (selector) and filtering (predicate) functions provided by the framework ( link ). 我鼓励您查看框架( 链接 )提供的不同映射(选择器)和过滤(谓词)函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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