【问题标题】:C# LINQ multiple one to many includes with where conditionC# LINQ 多个一对多包含与 where 条件
【发布时间】:2015-07-03 22:07:24
【问题描述】:

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

我有三个示例表:

  • 员工(身份证、姓名、电话)
  • EmployeeDepartment(Id、EmployeeId、DepartmentId)
  • DepartmentAddress(ID、DepartmentId、城市、 街道,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 条件的部门时,我得到了所有部门和所有员工部门。什么查询会返回我需要的数据?

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答。不是只有一对一的关系才有效吗?
    • 试试看 :) 是否一对一都没关系,如果它不起作用,至少发布您需要使用的属性的实体。
    • @MattheW 假设它是多对一的关系,其中每个员工都有一个部门,每个部门都有一个地址,它将起作用。这取决于您在多对一中导航的方向。
    • 其实恰恰相反——一个员工可以分配到多个部门,一个部门可以分配多个地址。抱歉,如果在原始问题中不清楚。 :(
    【解决方案2】:

    也许是这样的:

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

    【讨论】:

    • 我无法对此进行测试,但如果可行,我建议检查生成的 SQL 以了解实体框架如何解析此查询。
    【解决方案3】:

    “我正在尝试编写实体框架查询,例如,它将返回分配给纽约市部门的所有员工。”

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

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

    希望我没有语法错误。这假设员工与部门之间的关系是多对一的。 IE。许多员工在一个部门。

    如果两种关系都相反:

    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();
    

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

    【讨论】:

    • 感谢您的回答。实际上恰恰相反——一个员工可以分配到多个部门,一个部门可以分配多个地址。抱歉,如果原始问题中不清楚。
    • @MattheW 我添加了另一个可能对您有所帮助的示例。
    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    相关资源
    最近更新 更多