后续两个 FROM 子句被转换为对SelectMany
的调用。
a)
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) 的回答为true,则即使在以下示例中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
(即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.Orders
返回的集合(即c
):
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) 问题?
谢谢
答案 0 :(得分:2)
查询get编译为:
collection1
.SelectMany(c1 => collection2, (c1, c2) => new { c1, c2 })
.SelectMany(t0 => collection3, (t0, c2) => new { t0.c1, t0.c2, c3 })
;
collection2
枚举collection1
中的每个元素;对于结果中的每个项目组合,都会枚举collection3
。
如果collection1
包含{ 1, 2 }
,collection2
包含{ 11, 12 }
,collection3
包含{ 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 })
;
对于通过过滤器的collection3
和collection1
的每个项目组合,都会枚举 collection2
。
对于查询d,每个c_3
都是groupB
中与groupA
中的元素匹配的项目列表,因此,如果我正确理解您的术语,则确实是“绑定到“a
。