簡體   English   中英

LINQ 加入多個 From 子句

[英]LINQ Join with Multiple From Clauses

在 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 在他的博客上談到了它。 (向下滾動到次要“從”子句。)

您列出的代碼:

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

... 將為company變量中的每個公司生成每個員工的列表。 如果一名員工為兩家公司工作,他們將兩次被列入名單。

這里可能發生的唯一“加入”是當您說c.Employees時。 在 SQL 支持的提供程序中,這將轉換為從Company表到Employee表的內部聯接。

然而,double- 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};

最后一個查詢將為您提供公司和員工的所有可能組合。

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

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

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM