简体   繁体   English

LINQ 加入多个 From 子句

[英]LINQ Join with Multiple From Clauses

When writing LINQ queries in C#, I know I can perform a join using the join keyword.在 C# 中编写 LINQ 查询时,我知道我可以使用join关键字执行连接。 But what does the following do?但是以下是做什么的?

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

A LINQ book I have say it's a type of join, but not a proper join (which uses the join keyword).一本 LINQ 书我说过这是一种连接,但不是正确的连接(使用join关键字)。 So exactly what type of join is it then?那么究竟是什么类型的连接呢?

Multiple "from" statements are considered compound linq statments.多个“from”语句被视为复合 linq 语句。 They are like nested foreach statements.它们就像嵌套的 foreach 语句。 The msdn page does list a great example here msdn 页面确实在此处列出了一个很好的示例

var scoreQuery = from student in students
                 from score in student.Scores
                 where score > 90
                 select new { Last = student.LastName, score };

this statement could be rewritten as:该语句可以重写为:

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

This will get translated into a SelectMany() call.这将被转换为SelectMany()调用。 It is essentially a cross-join.它本质上是一个交叉连接。

Jon Skeet talks about it on his blog, as part of the Edulinq series .作为Edulinq 系列的一部分,Jon Skeet 在他的博客上谈到了它。 (Scroll down to Secondary "from" clauses .) (向下滚动到次要“从”子句。)

The code that you listed:您列出的代码:

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

... will produce a list of every employee for every company in the company variable. ... 将为company变量中的每个公司生成每个员工的列表。 If an employee works for two companies, they will be included in the list twice.如果一名员工为两家公司工作,他们将两次被列入名单。

The only "join" that might occur here is when you say c.Employees .这里可能发生的唯一“加入”是当您说c.Employees时。 In an SQL-backed provider, this would translate to an inner join from the Company table to the Employee table.在 SQL 支持的提供程序中,这将转换为从Company表到Employee表的内部联接。

However, the double- from construct is often used to perform "joins" manually, like so:然而,double- from结构通常用于手动执行“连接”,如下所示:

from c in companies
from e in employees
where c.CompanyId == e.CompanyId
select e;

This would have a similar effect as the code you posted, with potential subtle differences depending on what the employees variable contains.这将具有与您发布的代码类似的效果,但可能存在细微差异,具体取决于employees变量包含的内容。 This would also be equivalent to the following join :这也等同于以下join

from c in companies
join e in employees
   on c.CompanyId equals e.CompanyId
select e;

If you wanted a Cartesian product, however, you could just remove the where clause.但是,如果您想要笛卡尔积,则可以删除where子句。 (To make it worth anything, you'd probably want to change the select slightly, too, though.) (不过,为了让它物有所值,您可能还想稍微更改select 。)

from c in companies
from e in employees
select new {c, e};

This last query would give you every possible combination of company and employee.最后一个查询将为您提供公司和员工的所有可能组合。

All the first set of objects will be joined with all the second set of objects.所有第一组对象将与所有第二组对象连接。 For example, the following test will pass...例如,以下测试将通过...

    [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