我是Linq的新手,在两个上下文中使用时对from
子句有疑问:
1)执行交叉连接,如下面的查询
var q1 = from person in people
from job in jobs
select new {person, job}
2)执行外连接
var q2 = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj
select new { OwnerName = person.FirstName, PetName = subpet.Name };
第二个from子句是作为交叉连接还是根据上下文进行评估?因为 q1将生成people.Count * jobs.Count元素 但是q2只会产生people.Count
答案 0 :(得分:3)
根据MS文档,要使第二个查询成为左外连接,您应该使用看到here的DefaultIfEmpty方法。 from子句总是以相同的方式计算:它返回序列中的每个元素,它是预定义的源还是上下文变量。
编辑:我会从一开始就尝试解释。首先你内心加入(群体加入,具体)人和宠物。然后从生成的集合(实际上是人 - 宠物集)中选择新的匿名对象,获取人名(来自gj set元素)和子地名(对于gj set元素中的每个宠物)。我认为第二个不做交叉连接,因为它从gj中选择,并且每个人已经是gj set元素的一部分。如果在第二个from子句中调用gj.DefaultIfEmpty()方法,那么没有任何宠物的人(在gj set元素中具有空宠物集合)将被添加到结果集中。您可以阅读以下文章以更好地理解它:
答案 1 :(得分:0)
join
通常用于根据匹配键关联两个序列的元素,因此通常是内部联接,但它取决于您定义的匹配项,例如以下将产生交叉连接:
List<int> A = new List<int> { 1, 2, 3, 4, 5 };
List<int> B = new List<int> { 1, 2, 3, 4, 5 };
var c = (from a in A join b in B on 1 equals 1 select new { a, b }).ToList();
答案 2 :(得分:0)
From基于上下文进行评估。如果不是,您将无法使用gj
等上下文变量。但是,如果您不使用该上下文,例如在第一个查询中,它的行为与交叉连接相同。
您说第二个查询会为您提供意外数量的元素。也许你不应该专注于那个,而是关注你得到的元素以及它与你期望的不同。