LINQ加入多个From子句

Jon*_*ood 47 c# linq

在C#中编写LINQ查询时,我知道我可以使用join关键字执行连接.但是以下是做什么的?

from c in Companies
from e in c.Employees
select e;
Run Code Online (Sandbox Code Playgroud)

一本LINQ书我说它是一种连接,但不是一个正确的连接(使用join关键字).那么究竟是什么类型的连接呢?

Nat*_*lus 49

多个"from"语句被认为是复合linq语句.它们就像嵌套的foreach语句.MSDN的页面确实列出一个很好的例子在这里

var scoreQuery = from student in students
                 from score in student.Scores
                 where score > 90
                 select new { Last = student.LastName, score };
Run Code Online (Sandbox Code Playgroud)

这句话可以改写为:

SomeDupCollection<string, decimal> nameScore = new SomeDupCollection<string, float>();
foreach(Student curStudent in students)
{
   foreach(Score curScore in curStudent.scores)
   {
      if (curScore > 90)
      {
         nameScore.Add(curStudent.LastName, curScore);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)


Ken*_*isa 29

这将被转换为一个SelectMany()电话.它本质上是一个交叉连接.

作为Edulinq系列的一部分,Jon Skeet在他的博客上谈到了这一点.(向下滚动到辅助"from"子句.)


Str*_*ior 19

您列出的代码:

from c in company
from e in c.Employees
select e;
Run Code Online (Sandbox Code Playgroud)

...将为company变量中的每个公司生成每个员工的列表.如果一名员工为两家公司工作,他们将被列入清单两次.

这里唯一可能出现的"加入"是你说的c.Employees.在SQL支持的提供程序中,这将转换为从Company表到Employee表的内部联接.

但是,双from构造通常用于手动执行"连接",如下所示:

from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;
Run Code Online (Sandbox Code Playgroud)

这将与您发布的代码具有类似的效果,根据employees变量包含的内容可能存在细微差别.这也等同于以下内容join:

from c in companies
join e in employees
   on c.CompanyId equals e.CompanyId
select e;
Run Code Online (Sandbox Code Playgroud)

但是,如果您想要笛卡尔积,则可以删除该where子句.(为了使它有价值,你可能也想select稍微改变一下.)

from c in companies
from e in employees
select new {c, e};
Run Code Online (Sandbox Code Playgroud)

最后一个查询将为您提供公司和员工的所有可能组合.