Linq - 关于“Any”方法的问题

6
假设我对AdventureWorks数据库有以下查询:
var result = from customer in Customer
    where customer.CustomerAddress.Any (ca => ca.Address.City == "Dallas")
    select new
    {
        customer.Individual.Contact.FirstName,
        Addresses = customer.CustomerAddress
    };

这个查询将返回所有居住在达拉斯的客户。然而,我不确定它为什么能够工作。我知道“Any”方法根据序列中是否有任何一行满足谓词返回布尔值。但是以这种方式使用时,它似乎实际上返回了满足谓词的一系列行。我猜我不确定这里到底发生了什么。
然而,以以下方式使用,“Any”如何工作就很容易理解:
var result = Customer.Any (c => c.CustomerAddress.Any (ca => ca.Address.City == "Largo" ) );

返回false的原因是没有客户居住在拉戈镇。


你不明白的是什么?是第一个例子返回行还是第二个例子布尔值? - archil
6个回答

11
第一个查询可以理解为:返回所有在达拉斯有地址的客户。 查询结果为“这些就是那些客户”。第一个查询使用了 Any 关键字,严格针对地址。因此,返回拥有满足 Any 的地址的客户。
第二个查询可以理解为:“我是否有任何在 Largo 有地址的客户?” 结果要么是是或否(真或假)。你已经将 Any 应用于地址和 Any 在地址上的结果,因此查询的第一部分是“按照住址过滤客户”,第二部分是“现在我只想知道是否有这样的客户。”
现在明白了吗?

4

Any返回一个布尔值,但它被传递到where子句中。 where子句接受一个布尔表达式,将其应用于序列中的每个项,并返回那些表达式为真的项。因此,在扩展方法语法中,您的查询将被翻译为:

var result = Customer
             .Where(customer => customer.CustomerAddress.Any(ca => ca.Address.City == "Dallas"))
             .Select(customer => new { /*...*/ });

你的第二个例子几乎完全相同,只是使用了外部的 Any 代替了 Where。这里是与上面的代码格式匹配的代码:

var result = Customer
             .Any(c => c.CustomerAddress.Any(ca => ca.Address.City == "Largo"));

简化一下,就更加清楚正在发生的事情了:
var result1 = Customer
              .Where(customer => customer.HasAnyAddressHere);

var result2 = Customer
              .Any(customer => customer.HasAnyAddressHere);

我们发现Where子句是第一个查询的主要驱动因素。您可以用英语写成:

给我所有在达拉斯至少有一个地址的客户。忽略他们的其他地址。如果客户没有达拉斯的地址,请将其从结果中过滤掉。

正如您所看到的,这是要求客户列表。第二个查询为:

是否存在至少一个客户在达拉斯至少有一个地址?

这是一个是/否问题,因此它返回true或false。


1

以下是您的两个示例重写为方法语法(第一个示例在您的示例中为混合语法,第二个示例已经使用了方法)

    IEnumerable result = Customers
    .Where(c => c.CustomerAddress.Any(ca => ca.Address.City == "Dallas"))
    .Select(c=> new { FirstName = c.Individual.Contact.FirstName, Addresses = c.Addresses};

    //vs

    bool result = Customers.Any (c => c.CustomerAddress.Any (ca => ca.Address.City == "Dallas" ) );

看到这些任务了吗?第一条语句以 Select => 结尾,返回可枚举对象。第二条语句以 Any => 结尾,返回布尔值。


1

您正在获取满足谓词条件的行列表,因为您正在将Any方法用作select语句的where子句,该语句将选择一组行。

因此,您的第一个示例表示“选择所有地址为达拉斯的客户”。Any不会返回行列表(它只是作为where子句的条件),select语句才会返回行列表。


1

where语句会对Customer中的每个元素进行评估(关于每个客户的是或否)。因此,您将获得所有地址城市为Dallas的客户。

第二个语句明确表示告诉我是否有任何客户的地址城市为Largo。(是或否)


1
对于每个 Customer,当 customerCustomerAddresses 集合中至少有一个 AddressCity 字段与 "Dallas" 匹配时,选择 "客户的名字和地址集合"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接