4

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

?

谢谢

4

2 回答 2

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)无论上下文如何,总是多余的。它只是意味着“对于序列中的每个元素,选择元素”。

第二个片段当然不同,SelectManyandSelect语句确实需要嵌套才能选择所有三个元素c_1c_2c_3

不过,就像 Gert 所说,您最好还是使用查询理解语法。它更加简洁,并且更容易在心理上解析查询的工作原理。

于 2012-10-22T19:03:41.643 回答
1

一种。查询是相等的,因为在这两种情况下,您最终都会得到 all c_3's in c_1through c_2

湾。您无法按照您的建议访问c_1c_2处理这些查询。如果你想要,你需要这个重载的SelectMany. 这种“流利”的语法虽然很笨拙。这通常是一种情况,其中执行相同操作的综合语法要好得多:

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 }
于 2012-10-22T19:18:26.160 回答