我可以使用导航属性执行连接,这对我来说更干,因为我没有在任何地方重复连接标准:
(from c in db.Companies
from e in c.Employees
select new { Employee = e, Company = c}).ToList();
由于ORM知道公司与员工的关系,c.Employees
导航属性用于推断加入的FK标准。
通过导航属性直接转换为from from子句的扩展/ lambda语法是什么?
我知道有一个Join扩展方法,但是要求你明确命名要比较的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
,但想法以某种方式使用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
。我不知道你是否可以在扩展方法中表达相同的东西,这样就传递了所有三个别名/引用。也许只是扩展方法语法的结果,但希望有人能提供更好的等价物。
答案 0 :(得分:5)
不会只是这样:
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();
答案 1 :(得分:5)
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,
});
请参阅this blog post以获取更多详细信息以及对此转换的深入描述,以及它如何扩展。