2011-06-06 58 views
35

在C#中編寫LINQ查詢時,我知道我可以使用join關鍵字執行加入。但是下面是做什麼的?LINQ加入多個子句

from c in Companies 
from e in c.Employees 
select e; 

一個LINQ本書中,我說這是一個連接類型,但不正確的連接(使用join關鍵字)。那麼到底是什麼類型的連接呢?

+1

Linq-to-Objects,-Sql,-Entities?在-Objects中,這不是一個連接,而是一個'SelectMany'操作。在其他情況下,可以根據數據將其翻譯爲左側或內側。 – 2011-06-06 19:42:23

+0

@Anthony:我還沒有用過那麼多的LINQ。所以我的問題只是一般而已,並不侷限於任何特定的提供者。但是,最終,我最終可能會使用LINQ to Entities。 – 2011-06-06 20:25:17

回答

39

多個「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); 
     } 
    } 
} 
24

這將被翻譯成SelectMany()調用。它本質上是一個交叉連接。

Jon Skeet在他的博客上談到這個問題,作爲Edulinq series的一部分。 (向下滾動至次要「從」條款。)

-1

所有第一組對象將與所有第二組對象連接。例如,以下測試將通過...

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

    } 
+1

這與問題中的代碼不同。你正在展示一個笛卡爾產品,這不是這個。 – 2011-06-06 19:48:36

16

你列出的代碼:

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}; 

這最後一個查詢會給你的公司和員工的每一個可能的組合。