在C#中编写LINQ查询时,我知道我可以使用join
关键字执行加入。但是下面是做什么的?LINQ加入多个子句
from c in Companies
from e in c.Employees
select e;
一个LINQ本书中,我说这是一个连接类型,但不正确的连接(使用join
关键字)。那么到底是什么类型的连接呢?
在C#中编写LINQ查询时,我知道我可以使用join
关键字执行加入。但是下面是做什么的?LINQ加入多个子句
from c in Companies
from e in c.Employees
select e;
一个LINQ本书中,我说这是一个连接类型,但不正确的连接(使用join
关键字)。那么到底是什么类型的连接呢?
多个“from”语句被视为复合linq语句。它们就像嵌套的foreach语句。 MSDN的页面确实列出一个很好的例子here
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()
调用。它本质上是一个交叉连接。
Jon Skeet在他的博客上谈到这个问题,作为Edulinq series的一部分。 (向下滚动至次要“从”条款。)
所有第一组对象将与所有第二组对象连接。例如,以下测试将通过...
[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);
}
这与问题中的代码不同。你正在展示一个笛卡尔产品,这不是这个。 – 2011-06-06 19:48:36
你列出的代码:
from c in company
from e in c.Employees
select e;
...会产生一个列表在company
变量中的每个公司的每个员工的总数。如果员工为两家公司工作,他们将被列入清单两次。
这里可能发生的唯一“加入”是当您说c.Employees
时。在SQL支持的提供程序中,这将转换为从Company
表到Employee
表的内部联接。
然而,双from
结构通常用于执行“加入”手动,像这样:
from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;
这将产生类似的效果,你发布的代码,以根据潜在细微的差别是什么包含employees
变量。这也将是等效于下面的join
:
from c in companies
join e in employees
on c.CompanyId equals e.CompanyId
select e;
如果你想要一个笛卡尔乘积,但是,你可以只取出where
条款。 (使它值得任何东西,你可能会想改变select
咯,太,虽然)。
from c in companies
from e in employees
select new {c, e};
这最后一个查询会给你的公司和员工的每一个可能的组合。
Linq-to-Objects,-Sql,-Entities?在-Objects中,这不是一个连接,而是一个'SelectMany'操作。在其他情况下,可以根据数据将其翻译为左侧或内侧。 – 2011-06-06 19:42:23
@Anthony:我还没有用过那么多的LINQ。所以我的问题只是一般而已,并不局限于任何特定的提供者。但是,最终,我最终可能会使用LINQ to Entities。 – 2011-06-06 20:25:17