[英]Lambda Syntax for Joins via Navigation Property?
我可以使用导航属性执行连接,这对我来说更干,因为我没有在任何地方重复连接标准:
(from c in db.Companies
from e in c.Employees
select new { Employee = e, Company = c}).ToList();
由于ORM知道公司与员工的关系,因此c.Employees
导航属性用于推断连接的FK标准。
什么是通过导航属性直接转换为multiple from子句的扩展/ lambda语法?
我知道有一个Join扩展方法,但是要求您明确命名要比较的FK,而不是它通过navigation属性暗示该条件。 这是不工作的,但希望表达我的意图:
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
,但想法以某种方式使用Companies.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 });
由于每个员工都有公司,为什么不将导航属性“公司”添加到员工实体?
要获得假期,只需将其更改为以下内容:
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();
和:
(from e in c.Employees
from c in db.Companies
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,
});
请参阅此博客文章 ,了解更多详细信息以及对此转换的深入描述,以及它如何扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.