Ken*_*eth 29 c# linq database entity-framework
我有一个实体Person,它有一个与之关联的位置列表.我需要查询人员表并从位置列表(标准)中获取至少有一个位置的所有人员.以下工作但效率很低:
var searchIds = new List<int>{1,2,3,4,5};
var result = persons.Where(p => p.Locations.Any(l => searchIds.Any(id => l.Id == id)));
Run Code Online (Sandbox Code Playgroud)
这适用于小型列表(例如5-10个searchIds和5-10个位置的人.问题是有些人可能有100个位置,搜索也可以同时用于100个位置.当我尝试执行上述操作时EF实际上产生了一个2000+以上的SQL语句并因为嵌套太深而失败.虽然嵌套本身已经是一个问题,即使它可以工作,我仍然不会发生2000+ SQL语句.
注意:真正的代码还包括多个级别和父子关系,但我确实设法只使用id而不是完整对象将其归结为这个相当扁平的结构
在EF中实现这一目标的最佳方法是什么?
Ivo*_*Ivo 59
我建议:
var searchIds = new List<int>{1,2,3,4,5};
var result = persons.Where(p => p.Locations.Any(l => searchIds.Contains(l.Id)));
Run Code Online (Sandbox Code Playgroud)
Contains
将被翻译成IN
声明.
请记住,id列表会进入sql语句.如果你的id列表很大,那么你最终会得到一个巨大的查询.
尝试切换到联接而不是执行大量数据包括:
var searchIds = new List<int>{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();
Run Code Online (Sandbox Code Playgroud)
显然,修复此行以匹配您的类和/或连接属性.
join l in Location on p.PersonId equals l.PersonId
Run Code Online (Sandbox Code Playgroud)
我希望能够产生更友好的执行计划.