检查列表是否包含EntityFramework中其他列表中的项目

我有一个实体Person,它有一个与之关联的位置列表。 我需要查询人员表并从位置列表(标准)中获取至少有一个位置的所有人员。 以下工作但效率很低:

var searchIds = new List{1,2,3,4,5}; var result = persons.Where(p => p.Locations.Any(l => searchIds.Any(id => l.Id == id))); 

这适用于小型列表(例如5-10个searchIds和5-10个位置的人。问题是有些人可能有100个位置,搜索也可以同时为100个位置。当我尝试执行上述操作时EF实际上产生了一个2000+以上的SQL语句并因为嵌套太深而失败了。虽然嵌套本身已经是一个问题,即使它可以工作,但我仍然不会发生2000+ SQL语句。

注意:真正的代码还包括多个级别和父子关系,但我确实设法使用id而不是完整对象将其归结为这个相当扁平的结构

在EF中实现这一目标的最佳方法是什么?

我建议:

 var searchIds = new List{1,2,3,4,5}; var result = persons.Where(p => p.Locations.Any(l => searchIds.Contains(l.Id))); 

Contains将被翻译为IN语句。

请记住,id列表会进入sql语句。 如果你的id列表很大,那么你最终会得到一个巨大的查询。

尝试切换到联接而不是执行大量数据包括:

 var searchIds = new List{1,2,3,4,5}; var results = (from p in persons join l in Location on p.PersonId equals l.PersonId where searchIds.Contains(l.Id) select p).Distinct().ToList(); 

显然,修复此行以匹配您的类和/或连接属性。

 join l in Location on p.PersonId equals l.PersonId 

我希望能够产生更友好的执行计划。