2

我已经在 LINQ 查询中多次看到过多个 from 子句,但还没有弄清楚它与 TSQL 语句的对应关系。

var r = from p in products
        from d in departments
        from c in something
        select p;

那有什么作用?

这会转化为 SQLSELECT * FROM products, departments, something吗?

此外,select在这种情况下,应该始终是SelectMany. 我怎么知道什么时候 aselect实际上是 a SelectMany

4

3 回答 3

3

这将在概念上转化为代码,如下所示:

var r = products.SelectMany(p => departments, (p, d) = new { p, d })
                .SelectMany(z => something, (z, c) => new { z, c })
                .Select(zz => zz.z.p);

基本上from,在第一个之后的每个都会额外调用SelectMany. 实际上,在这种情况下,编译器会注意到在最后一个from子句之后只有一个select,它实际上会转换为:

var r = products.SelectMany(p => departments, (p, d) = new { p, d })
                .SelectMany(z => something, (z, c) => z.p);

...但我倾向于首先考虑“逻辑”形式。

请注意,在这种情况下,您没有在from子句中使用较早的范围变量,但您可以:

var query = from person in people
            from friend in person.Friends
            select person.Name + " is friends with " + friend.Name;
于 2012-02-21T08:02:02.623 回答
2

这如何对应于 TSQL 语句?

这取决于您使用from条款的方式。如果您使用:

var query = from d in context.Departments
            from e in context.Employees
            select d;

您的查询将是CROSS JOIN因为产品和使用的部门之间没有关系。所以像:

SELECT d.* FROM Departments AS d
CROSS JOIN Employees AS e

显然你应该避免交叉连接。如果您改为在 second 中使用导航属性from

var query = from d in context.Departments
            from e in d.Employees
            select d;

您将使用INNERLEFT JOIN(EF 将根据您在关系中的多重性映射决定使用哪一个)。所以像:

SELECT d.* FROM Departments AS d
LEFT OUTER JOIN Employees AS e ON d.Id = e.DepartmentId
于 2012-02-21T08:59:22.550 回答
0

在这种情况下,使用 select 没有任何意义(它在语义上不正确,您必须使用 SelectMany)

于 2012-02-21T08:04:19.017 回答