繁体   English   中英

通过导航属性连接的Lambda语法?

[英]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的上下文中拥有cev 我不知道你是否可以在扩展方法中表达相同的东西,这样就传递了所有三个别名/引用。 也许只是扩展方法语法的结果,但希望有人能提供更好的等价物。

它不会像这样:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM