外部连接linq

本文关键字:linq 连接 外部 | 更新日期: 2023-09-27 18:22:31

我是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会产生人。计数*个作业。Count元素但q2只会产生人。计数

外部连接linq

根据MS文档,要使第二个查询成为左外部联接,您应该使用DefaultIfEmpty方法,如下所示。from子句总是以相同的方式求值:它返回序列中的每个元素,它是预定义的源还是上下文变量。

编辑:我试着从头开始解释。一开始,你会加入(具体来说是加入团体)人们和宠物。然后,从生成的集合(实际上是个人宠物集)中选择新的匿名对象,获得个人名称(来自gj集元素)和子集名称(用于gj集中的每个宠物)。我认为第二个from不做交叉连接,因为它从gj中选择,并且每个人都已经是gj集合元素的一部分。如果你叫gj。在第二个from子句中的DefaultIfEmpty()方法,那么没有任何宠物的人(在gj-set元素中有空的宠物集合)将被添加到结果集中。你可以阅读以下文章来更好地理解它:

  • GroupJoin方法
  • 如何:执行左外部联接(C#编程指南)

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

From基于上下文进行评估。如果不是这样,您将无法使用像gj这样的上下文变量。但是,如果不使用该上下文,就像在第一个查询中一样,它的行为与交叉联接相同。

您的意思是,第二个查询提供了意外数量的元素。也许你不应该关注这一点,但要关注你得到了什么元素,以及这与你的预期有何不同。