【问题标题】:Entity Framework filtering list within object对象内的实体框架过滤列表
【发布时间】:2018-01-11 18:40:37
【问题描述】:

我正在尝试过滤实体框架中的对象中的集合。我遵循this 示例,这是有道理的。

这是我的查询结果:

var filteredClientEmp = context.Clients.Include(x => x.CompanyEmployee)
                .Where(c => c.HrPersonId == paId && c.CompanyEmployee.Any(e => e.EmployeeBirthday != null && e.EmpType == 2 &&
                                                                                    e.LeftCompany == null))
                .Select(c => new
                {
                    c,
                    CompanyEmployee =
                    c.CompanyEmployee.Where(e => e.EmployeeBirthday != null && e.EmpType == 2 &&
                                                 e.LeftCompany == null)
                })
                .ToList()
                .Select(pro => pro.c)
                .ToList();

            return filteredClientEmp;

但是,当我检查 filteredClientEmp 对象时,它包含没有生日的员工以及左侧公司值不等于 null 的记录。

Client 对象有一个Employee 的非虚拟列表:

 public List<Employee> CompanyEmployee { get; set; }

为什么这个过滤不起作用?

【问题讨论】:

  • context 是否干净 (new)?这是什么 EF 版本?
  • 所以这可能是 ef-core 并且 Include 是可操作的,因为完整的 Client 是投影的一部分。
  • 这是 EF Core 对不起,上下文是干净和新的

标签: c# entity-framework


【解决方案1】:

Include() 无条件加载所有子实体。因为您投影到具有两个属性的匿名类型:

  • c: 客户及其所有员工
  • CompanyEmployee: 你的条件适用的那个客户的员工

然后继续仅投影c,这个c 仍然包括所有员工。您需要用过滤后的集合覆盖c 的 CompanyEmployee 集合:

.Select(p => { p.c.CompanyEmployee = p.CompanyEmployee; return p.c; })

【讨论】:

  • 这是我最初的想法。但是Includes 对于投影查询通常会被忽略,所以肯定有别的东西。
  • @Ivan 你是什么意思?那c.CompanyEmployee 应该是nullSelect()?
  • 我的意思是 (1) Include 应该没有效果,因为投影 (Select) (2) 通常不需要分配 p.c.CompanyEmployee = ...,因为应该已经分配了集合并在 ToList 调用期间填充(通过 EF 导航属性修复)。但它可能会有所帮助 :) 整个技术是一种 hack,因此可能由于多种原因而失败。
  • @Ivan (1):(假设 EF6):除非启用延迟加载,否则您需要 Include() 实际希望从查询中返回的实体。 (2) 需要赋值,因为包含的集合需要过滤。还是我错过了什么? EF Core 是否以不同的方式执行此操作?我还没有那么密集地使用它。
  • 无论是哪个版本,Include 都应该从查询中删除。关系修复将填充过滤的集合。不涉及延迟加载,因为集合不是 virtual 或者因为这是 ef-core。有点沮丧的是,在提出问题后 OP 似乎没有待命......
【解决方案2】:

你的问题出在:

.Select(pro => pro.c).ToList();

您不会返回过滤员工列表的客户:

CompanyEmployee = c.CompanyEmployee.Where(e => e.EmployeeBirthday != null && e.EmpType == 2 && e.LeftCompany == null)

事实上,如果匿名类型根本不使用该属性。相反,您将返回所有客户端的过滤列表:

1) 具有指定的 HrPersonId 和

2) 有至少一名员工过生日,员工类型为 2 且未离开公司。

要返回带有过滤列表的客户,您的最终选择应如下所示:

.Select(pro => { pro.c.CompanyEmployee = pro.CompanyEmployee; return pro.c; })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多