这两个LINQ查询可以互换使用吗?

时间:2012-10-22 18:39:46

标签: c# linq linq-to-objects

a)以下两个查询是否会产生相同的结果:

  var query1 = collection_1
            .SelectMany(c_1 => c_1.collection_2)
            .SelectMany(c_2 => c_2.collection_3)
            .Select(c_3 => c_3);

  var query2 = collection_1
            .SelectMany(c_1 => c_1.collection_2
            .SelectMany(c_2 => c_2.collection_3.Select(c_3 => c_3)));

b)我假设这两个查询不能总是互换使用?例如,如果我们希望输出元素还包含c_1c_2的值,那么我们只能使用query2实现此目标,而不能使用query1

  var query2 = collection_1
            .SelectMany(c_1 => c_1.collection_2
            .SelectMany(c_2 => c_2.collection_3.Select(c_3 => new { c_1, c_2, c_3 } )));

谢谢

2 个答案:

答案 0 :(得分:1)

您提供的摘录似乎无效。 c_3语句的范围中没有定义Select,所以除非我误解了某些内容,否则无法编译。

好像您正在尝试选择collection_3的元素,但这是由SelectMany隐式完成的,因此两种情况下的最终Select语句都是多余的。拿出来,两个查询是等价的。

所有你需要的是:

var query = collection_1
           .SelectMany(c_1 => c_1.collection_2)
           .SelectMany(c_2 => c_2.collection_3);

更新: x => x是标识映射,因此Select(x => x)始终是冗余的,无论上下文如何。它只是意味着“对于序列中的每个元素,选择元素”。

第二个代码段当然是不同的,SelectManySelect语句确实需要嵌套才能选择所有三个元素c_1c_2,和c_3

就像Gert说的那样,你可能最好使用查询理解语法。它更简洁,更容易在精神上解析查询的工作。

答案 1 :(得分:1)

一个。查询是相同的,因为在这两种情况下,您最终都会c_3c_1中的所有c_2

湾根据您的建议,您无法使用这些查询到达c_1c_2。如果您需要,SelectMany需要this重载。这种“流畅”的语法虽然非常笨拙。这通常是一种情况,其中相同的综合语法要好得多:

from c_1 in colection_1
from c_2 in c_1.collection_2
from c_3 in c_2.collection_3
select new { c_1.x, c_2.y, c_3.z }