【问题标题】:EF Core 5 check if all ids from filter exists in related entitiesEF Core 5检查过滤器中的所有ID是否存在于相关实体中
【发布时间】:2021-12-11 08:51:07
【问题描述】:

我有两个模型:

public class Employee
{
    public int Id { get; set; }
    public IList<Skill> { get; set; }
}

public class Skill
{
    public int Id { get; set; }
}

我有一个包含技能 ID 列表的过滤器,该员工应包含:

public class Filter
{
    public IList<int> SkillIds { get; set; }
}

我想编写查询来获取所有具有过滤器技能的员工。

我试过了:

query.Where(e => filter.SkillIds.All(id => e.Skills.Any(skill => skill.Id == id)));

还有:

query = query.Where(e => e.Skills
                .Select(x => x.Id)
                .Intersect(filter.SkillIds)
                .Count() == filter.SkillIds.Count);

但结果我得到异常说无法翻译查询。

【问题讨论】:

    标签: c# asp.net .net .net-core entity-framework-core


    【解决方案1】:

    在 sql server 端运行这样的查询将是一项艰巨的任务,如果不是不可能的话。 这是因为要在 SQL 端进行这项工作,您需要将每组员工技能分组到一行中,这需要为skills 表中列出的每个技能都有一个新列。 SQL Server 并没有真正用来处理传递给查询的一组未知列的分组。虽然这种查询在技术上是可行的,但通过 ef core 这样的模型绑定框架可能不太容易做到。

    在 .net 端使用类似这样的东西会更容易:

    var employees = _context.Employees.Include(x=>x.Skill).ToList();
    var filter = someFilter;
    var result = employees.Where(emp => filter.All(skillID=> emp.skills.Any(skill=>skill.ID == skillID))).ToList()
    

    【讨论】:

    • 感谢您的回答!我用找到的解决方案添加了答案
    【解决方案2】:

    此解决方案有效:

    foreach (int skillId in filter.SkillIds)
    {
        query = query.Where(e => e.Skills.Any(skill => skill.Id == skillId));
    }
    

    我不确定它的性能,但在少量数据的情况下运行速度很快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 2021-06-27
      • 1970-01-01
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多