C#LINQ多个一对多包含where where condition

时间:2015-07-03 22:07:25

标签: c# linq entity-framework

我找不到正确的查询来获取我需要的所有数据。

我有三个样本表:

  • 员工(身份证,姓名,电话)
  • EmployeeDepartment(Id,EmployeeId,DepartmentId)
  • DepartmentAddress(Id,DepartmentId,City, 街,IsActive ......)

每个表与下一个表都有一对多的关系。可以将员工分配到多个部门,并且可以为一个部门分配多个地址。

我试图编写实体框架查询,该查询将返回例如分配到纽约市的部门的所有员工。我的问题是我不想要雇员。我需要它还包括Employee类中EmployeeDepartment和DepartmentAddress的所有属性。

我试图做的事情是:

var matchingEmployees = ctx.Employee
.Include("EmployeeDepartment")
.Include("EmployeeDepartment.DepartmentAddress")
.Where(p=> p.EmployeeDepartment
.Where(x=>x.DepartmentAddress.Where(y=>y.City == "New York)))
.ToList();

因此,当我只需要符合Where条件的部门时,我会获得所有部门和所有EmployeeDepartments。什么查询将返回我需要的数据?

3 个答案:

答案 0 :(得分:0)

您不需要使用直接达到条件的地方。我认为它是这样的,如果你发布你的实体,它会更容易一些。

 var matchingEmployees = ctx.Employee
    .Include("EmployeeDepartment")
    .Include("EmployeeDepartment.DepartmentAddress")
    .Where(p=> p.DepartmentAddress.City == "New York)))
    .ToList();

答案 1 :(得分:0)

"我尝试做的是编写实体框架查询,例如,将返回分配到纽约市部门的所有员工。"

如果您对实际检索部门不感兴趣,并且只想过滤它们,那么加入会更合适。对于其他开发人员来说,更容易看到您的意图是缩小员工列表,而不是简单地缩小嵌套部门地址列表。这可以通过扩展语法(我更喜欢)来实现,但是连接在表达式语法中更具可读性:

var employeesInNewYorkDepartments = 
    (from employee in ctx.Employee
    let department = employee.EmployeeDepartment
    let departmentAddress = department.DepartmentAddress
    where departmentAddress.City == "New York" 
    select employee).ToList();

希望我没有语法错误。这假设从员工到部门的关系是多对一的。即许多员工都在一个部门。

如果两种关系都相反:

var employeesInNewYorkDepartments = 
    (from employee in ctx.Employee
    join department in employee.EmployeeDepartments    
    join departmentAddress in department.DepartmentAddresses
    where departmentAddress.City == "New York" 
    select employee).Distinct().ToList();

请注意,在向多个方向导航时,您的导航属性名称应为复数。它们代表对集合的访问,因此单个导航属性名称极具误导性。 (实体类名称仍然是单数,但它声明了单个项目的结构。)

答案 2 :(得分:0)

也许这个:

ctx.Employee
    .Include( e => e.EmployeeDepartment)
    .Include( e => e.EmployeeDepartment.DepartmentAddress)
    .Where(e => && e.EmployeeDepartment.DepartmentAddress.All(y => y.City == "New York")).ToList();