0

随后的两个FROM子句被转换为对SelectMany.

一种)

var query = from c_1 in collection_1
            from c_2  in collection_2 
            from c_3 in collection_3
            select ...

如果我错了,请纠正我,但我认为查询表达式被翻译成语义上等同于的代码:

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

总是from c_3 in collection绑定”到c_2范围变量吗?使用“绑定”一词,我在问是否collection_3为每个元素枚举了整个c_2元素?

b) 假设我在a)下是正确的,c_3总是“绑定”到最接近它定义的范围变量?

c) 如果对b)的回答为真,那么在以下示例中c_3也必然:c_2

var query = from c_1 in collection_1
            from c_2  in collection_2 
            where ...
            from c_3 in collection_3

d)在下一个查询中c_3绑定到a(即,对于每个a整体groupAandB都将被枚举):

var query_1 =  from a in groupA
               join b in groupB on a equals b
                  into groupAandB
               from c_3 in groupAandB
               select c_3;

e) 在这里,我假设d)的答案c_3确实是a. 但是当查看在query_1编译时被翻译成的代码时,我们可以争辩说它c_3实际上是绑定到匿名类型a_1( ie new { a, groupAandB = os })的?!

groupA.GroupJoin(groupB, a => a, b => b, (a, os) => new { a, groupAandB = os } ).
             SelectMany(a_1 => a_1.groupAandB );

f) 牢记要query_1翻译的内容,我们不能争辩说我在d)下所做的任何假设在概念上可能是正确的,但在技术上是错误的,因为在编译时没有任何c_3变量,或者可能在c_3某处定义在引擎盖下,但它实际上绑定到匿名类型而不是a

编辑:

1)

使用 Join,“第二个”集合不能依赖于您当前正在“查看”第一个集合中的哪个值,

a)我假设你的意思是我们不能加入由当前值返回customers的集合(即) :c.Ordersc

var query1 = from c in customers
             join o in c.Orders on c.CustomerId equals o.OrderID // this won't work
             select new { c.Name, o.OrderID, o.OrderDate };

b)顺便说一句,为什么不允许这样的加入(我假设进行这样的加入在技术上是可行的)或者为什么它没有意义?

2)

“C# 规范给出了所涉及的显式转换”

您能否详细说明“涉及的显式转换”的含义以及它与e)f)问题的关系?

谢谢你

4

1 回答 1

2

查询 a 被编译为:

collection1
   .SelectMany(c1 => collection2, (c1, c2) => new { c1, c2 })
   .SelectMany(t0 => collection3, (t0, c2) => new { t0.c1, t0.c2, c3 })
;

collection2为 中的每个元素枚举collection1collection3为结果中的每个项目组合枚举。

如果collection1contains { 1, 2 }collection2contains{ 11, 12 }collection3contains { 21, 22 },则结果将是:

|----|----|----|
| c1 | c2 | c3 |
|----|----|----|
|  1 | 11 | 21 |
|  1 | 11 | 22 |
|  1 | 12 | 21 |
|  1 | 12 | 22 |
|  2 | 11 | 21 |
|  2 | 11 | 22 |
|  2 | 12 | 21 |
|  2 | 12 | 22 |
|----|----|----|

查询 c 被编译为:

collection1
   .SelectMany(c1 => collection2, (c1, c2) => new { c1, c2 })
   .Where(t0 => ...)
   .SelectMany(t0 => collection3, (t0, c3) => new { t0.c1, t0.c2, c3 })
;

collection3collection1枚举来自和collection2通过过滤器的项目的每个组合。

对于查询 d, eachc_3将是与groupB中的元素匹配的项目列表groupA,因此,如果我正确理解了您的术语,它确实是“绑定到” a

于 2012-10-24T18:16:38.340 回答