EF Core 5检查过滤器中的所有ID是不是存在于相关实体中
Posted
技术标签:
【中文标题】EF Core 5检查过滤器中的所有ID是不是存在于相关实体中【英文标题】: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);
但结果我得到异常说无法翻译查询。
【问题讨论】:
【参考方案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));
我不确定它的性能,但在少量数据的情况下运行速度很快。
【讨论】:
以上是关于EF Core 5检查过滤器中的所有ID是不是存在于相关实体中的主要内容,如果未能解决你的问题,请参考以下文章