2017-01-06 13 views
3

我有2 LINQ查询,一个返回我期望的,另一个不,我试图理解为什么。我试图找出Config中的所有节点是否有一个名为“TEST”的节点,其Selected属性为True。这2个LINQ查询有什么区别?

查询1 - 它返回正确的事情有内部的任何条件():

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

查询2,它失败了,有内选择条件:

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

'Select'返回'IEnumerable '您需要使用'Where'来过滤输入序列。 – Lee

+0

'let name = config.name'在做什么?其无用的 –

+1

任何返回bollean,选择返回数据 –

回答

5

LINQ的Any()没有条件意味着“至少有一行”。第一个查询指定一个条件,使其“至少有一行匹配条件”。

要使第二个查询等同于第一个查询,请使用Any(flag => flag)或用Where替换Select。这两个选项都比最初的Any差,因为它们的内部条件不够好,因为它们不可读。

1

这里的整个事情是无用的。

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

您可以缩小它这个

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

将执行与您的代码第一个块。

Select方法使用您给出的选择器 将可枚举转换为另一种形式。 无参数Any如果序列包含任何元素,则返回true。否则返回false。

1

您可能也想尝试:

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

查看的是SelectAny方法的文档,可以提供一些见解。

如果你看看每这些链接的参数部分,你会看到,虽然这两种方法接受一个Func,它们的使用实际上是不同的。

不限

谓词 类型:System.Func<TSource, Boolean>甲函数来测试一个条件的每个 元件。

选择

选择 类型:System.Func<TSource, TResult>变换函数以便 应用到每个元件。

因此,在您查询1例如,你申请转换(或地图),以每件商品的集合,它声明一个局部变量的名称 let name = config.name(未使用),然后就回报该对象原样(没有实际转换任何东西)select config。这一点代码是多余的,可以删除。

您的Any() lambda通过过滤与您的lambda谓词不匹配的项目来完成Query1中的所有工作。

在Query2中,您将过滤lambda传递给转换函数,然后使用不带过滤器的过滤函数。

有很多不同的方法可以使用Linq获得您想要的结果。我鼓励你看看框架提供的不同映射(选择器)和过滤(谓词)功能(link)。