问题描述
|
用C#编写LINQ查询时,我知道可以使用
join
关键字执行联接。但是,以下是做什么的?
from c in Companies
from e in c.Employees
select e;
我曾说过一本LINQ书,它是一种联接类型,但不是正确的联接(使用join
关键字)。那么到底是什么类型的联接?
解决方法
多个\“ from \”语句被认为是复合linq语句。它们就像嵌套的foreach语句。 msdn页面确实在这里列出了一个很好的例子
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName,score };
该语句可以改写为:
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);
}
}
}
, 这将转换为SelectMany()
通话。它本质上是交叉联接。
作为Edulinq系列的一部分,Jon Skeet在他的博客中谈到了它。 (向下滚动到Secondary \“ from \”子句。)
, 您列出的代码:
from c in company
from e in c.Employees
select e;
...将在company
变量中生成每个公司的每个员工的列表。如果一名员工在两家公司工作,他们将被两次列入名单。
当您说c.Employees
时,唯一可能出现的\“ join \”。在SQL支持的提供程序中,这将转换为从from9ѭ表到Employee
表的内部联接。
但是,双11构造通常用于手动执行“ joins”,如下所示:
from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;
这将与您发布的代码具有相似的效果,并可能会因employees
变量包含的内容而存在细微差别。这也等效于以下“ 0”:
from c in companies
join e in employees
on c.CompanyId equals e.CompanyId
select e;
但是,如果要使用笛卡尔积,则可以删除where
子句。 (为使它物有所值,您可能也想稍稍更改change17ѭ。)
from c in companies
from e in employees
select new {c,e};
最后一个查询将为您提供公司和员工的所有可能组合。
, 所有第一组对象将与所有第二组对象结合在一起。例如,以下测试将通过...
[TestMethod()]
public void TestJoin()
{
var list1 = new List<Object1>();
var list2 = new List<Object2>();
list1.Add(new Object1 { Prop1 = 1,Prop2 = \"2\" });
list1.Add(new Object1 { Prop1 = 4,Prop2 = \"2av\" });
list1.Add(new Object1 { Prop1 = 5,Prop2 = \"2gks\" });
list2.Add(new Object2 { Prop1 = 3,Prop2 = \"wq\" });
list2.Add(new Object2 { Prop1 = 9,Prop2 = \"sdf\" });
var list = (from l1 in list1
from l2 in list2
select l1).ToList();
Assert.AreEqual(6,list.Count);
}