C# 通过导航属性连接的Lambda语法?
我可以使用导航属性执行连接,这对我来说比较枯燥,因为我不会到处重复连接条件:C# 通过导航属性连接的Lambda语法?,c#,linq,C#,Linq,我可以使用导航属性执行连接,这对我来说比较枯燥,因为我不会到处重复连接条件: (from c in db.Companies from e in c.Employees select new { Employee = e, Company = c}).ToList(); 因为ORM知道公司与员工的关系,所以使用c.Employees导航属性推断加入的FK标准 通过导航属性将multiple-from子句直接转换为extension/lambda语法是什么? 我知道有一个连接扩展方法,但要求您显
(from c in db.Companies
from e in c.Employees
select new { Employee = e, Company = c}).ToList();
因为ORM知道公司与员工的关系,所以使用c.Employees
导航属性推断加入的FK标准
通过导航属性将multiple-from子句直接转换为extension/lambda语法是什么?
我知道有一个连接扩展方法,但要求您显式地命名要比较的FK,而不是通过导航属性暗示条件。这是无效的,但希望能表达我的意图:
db.Companies
.Join(c.Employees, /* don't want to explicitly name FKs*/)
.Select(x => new { Employee = x.e, Company = x.c}).ToList();
当然,Join(c.Employees
不起作用,因为在此上下文中没有c
,但是想法是以某种方式使用companys.Employees导航属性来暗示加入标准
我知道我能做到:
db.Companies.Select(c => new { Employees = c.Employees, Company = c })
但这是一个不同的结果集,因为它会为每个公司返回一条记录,然后将员工列表作为嵌套属性。因此,每个相关组合都有一条记录,而不是第一条作为联接的记录,并且结果有一个Employee
属性,而不是employees
集合
我不确定,但是猜测。SelectMany
是直接翻译。您不会得到对父对象的c
引用,因此如果您执行以下操作中的多个操作:
db.Companies.SelectMany(c=>c.Employees).SelectMany(e=>e.VacationDays).Select(v => new { VacationDay = v, Employee = v.Employee, Company = v.Employee.Company })
在linq中,它要简单得多,因为在select的上下文中会有
c
、e
和v
。我不知道是否可以在扩展方法中表达相同的内容,以便所有三个别名/引用都被传递下来。也许只是这是扩展方法语法的结果,但希望有人能提供更好的等价物。这不是很像:
db.Employees.Select(m => new { Employee = m, Company = m.Company });
既然每个员工都有一个公司,为什么不将导航属性“Company”添加到员工实体中呢
要获得假期,只需将其更改为以下内容:
db.Employees.SelectMany(
employee => employee.VacationDays,
(employee, vacationDay) => new
{
Employee = employee,
Company = employee.Company,
VacationDay = vacationDay
});
更新:
事实上,两者之间没有区别:
(from c in db.Companies
from e in c.Employees
select new { Employee = e, Company = c}).ToList();
以及:
SelectMany
确实是多个from
子句映射到的内容
为了将变量保持在范围内,每个SelectMany
需要将序列投影到一个新的匿名对象中,该对象将所有适当的变量保持在范围内:
var query = db.Companies.SelectMany(company => company.Employees,
(company, employee) => new
{
company,
employee
});
要为其他嵌套导航属性添加其他投影,只需重复该模式,然后调用SelectMany
:
var query = db.Companies.SelectMany(company => company.Employees,
(company, employee) => new
{
company,
employee
}).SelectMany(pair => pair.employee.VacationDays,
(pair, vactionDay) => new
{
pair.company,
pair.employee,
vactionDay,
});
有关此转换的更多详细信息和深入描述,以及它的扩展方式,请参阅。他在
公司的Employee
上有一个导航属性。这就是他所使用的。他试图使用它将查询投影到员工和公司的成对集合中。他使用query做得很好y语法,但无法使用方法语法。您没有在此答案中对该查询语法查询进行建模。这正是我的查询所做的。我指定了方法语法,只是不同的方法。EF将执行正确的联接,就像使用查询方式执行时一样。我没有注意到您将其反转,但是的,确实如此,尽管确实如此esn没有回答如何将给定的查询语法查询实际转换为方法语法的问题。谢谢,这将有助于其他对另一种方法感兴趣的人,但取决于关系的基数,在Select
中对简单大小写以外的任何内容执行此类操作将变成cre中的练习积极性。并不是说Servy's总是更好,我只是想更好地理解我的LINQ表达式所代表的内容,看看直接翻译是否有吸引力。对我的答案补充了一点解释。目前唯一的问题是“哪种方式更快?”。如果您分析SQL查询结果并将其发布到某个地方,那将非常好。
var query = db.Companies.SelectMany(company => company.Employees,
(company, employee) => new
{
company,
employee
}).SelectMany(pair => pair.employee.VacationDays,
(pair, vactionDay) => new
{
pair.company,
pair.employee,
vactionDay,
});