我正在查看同事Linq查询,如下所示(查询正确执行):
from ea in EquipmentApplication
join erl in EquipmentRoutingLocation on ea.EquipmentID equals erl.EquipmentID into erlWithNulls
from erlAll in erlWithNulls.DefaultIfEmpty()
join rl in RoutingLocation on erlAll.RoutingLocationID equals rl.RoutingLocationID into rlWithNulls
from rlAll in rlWithNulls.DefaultIfEmpty()
where ea.Equipment.Master_Cell.Area.Unit.UnitID == 1160
select new { ea.Equipment, ea.ApplicationFriendlyName, rlAll }
我很困惑为什么会这样。我的理解(可能不正确)是'into'关键字结束当前范围/上下文(并且创建的任何变量现在都超出范围)并创建一个新的。如果这是真的,为什么'ea'变量仍然在查询的最后部分范围内?
答案 0 :(得分:34)
与select
关键字一起使用时,into
将结束范围
与join
关键字一起使用时,into
将添加一个包含联接中所有匹配项的变量。 (这称为Group Join)
答案 1 :(得分:21)
“into”有两个不同的含义:
join
子句中,它会将翻译从使用Join
更改为GroupJoin
。这意味着,不是每个匹配对获得一个结果,而是为原始序列的每个元素获得一个结果,并且该结果包含键和来自另一个序列的所有结果,作为一个组。有关详细信息,请参阅Enumerable.GroupJoin
select
或group...by
中,它变为query continuation,有效地在新范围变量中使用旧查询的结果开始新查询。答案 2 :(得分:16)
为了补充已经说过的内容,我想展示一下对象与否的对象结构的区别:
var q =
from c in categories
join p in products on c equals p.Category into ps
select new { Category = c, Products = ps };
创建一个对象图:
Category 1, Products:
Product 1
Product 2
Category 2, Products:
Product 3
Product 4
在这种情况下,q
只包含2个项目,即两个类别。
如果没有,你会得到一个更传统的联接,通过创建所有可能的组合来平衡关系:
var q =
from c in categories
join p in products on c equals p.Category
select new { Category = c, Product = p };
Category 1, Product 1
Category 1, Product 2
Category 2, Product 3
Category 2, Product 4
请注意,现在q
包含4个项目。
更新,我认为:
var q =
from c in categories
join p in products on c equals p.Category into ps
select new { Category = c, Products = ps.Select(x=> x.Id) };