EntityFramework 5过滤包含的导航属性

我想找到一种方法使用Linq将导航属性过滤到相关实体的子集。 我知道围绕这个主题的所有答案建议做一个匿名选择器,如:

query.Where(x => x.Users.Any(y => y.ID == actingUser.ID)) .Select(x => new { Event = x, Discussions = x.Discussions.Where(actingUser.GenerateSecurityFilterFor()) }) .OrderBy(x => x.Discussions.Count()) .ThenBy(x => x.Event.Name); 

但是,由于我们的查询生成的一般性质,这显然不太理想,如果你抛出探查器,也会产生非常可怕的SQL查询。

我希望能够完成以下事情:

 query.Include(x => x.Discussions.Where(actingUser.GenerateSecurityFilterFor())) .OrderBy(x => x.Discussions.Count()) .ThenBy(x => x.Name); 

我意识到EF5(或任何版本)都不支持这一点,但必须有一种方法可以通过Linq完成对结果集的约束,而无需深入研究匿名类型的select语句。

我试图做一些事情:

 query.GroupJoin(discquqery, x => x.ID, x => x.Event.ID, (evt, disc) => evt.Discussions = disc.Where(actingUser.GenerateSecurityFilterFor())).ToList(); 

但是,您无法在lambda表达式中进行赋值,并且选择匿名类型会导致使用select时遇到的相同困境。

我想我无法理解为什么EF没有提供一种方法(我能找到)来生成:

 SELECT --Properties FROM Event e LEFT OUTER JOIN Discussions d ON e.ID = d.EventID AND --Additional constraints WHERE --Where conditions ORDER BY --Order Conditions 

在SQL中约束连接是如此简单,HAS也是通过Linq实现它的一种方式。

PS:我已经搜索了堆栈,MSDN,专家交流等。请认识到这不是重复。 任何甚至触及这个主题的事情要么都有“无法完成”的答案,要么根本没有答案。 没有什么是不可能的……包括这个。

任何甚至触及这个主题的事情要么都有“无法完成”的答案,要么根本没有答案。 没有什么是不可能的……包括这个。

当然。 有可能的。 您可以下载EF源代码并自行添加此function。 这将对开源项目和社区做出巨大贡献。 我相信EF团队很乐意帮助您。

目前的版本“无法完成” 就是答案 。 您可以使用投影到匿名或特殊的未映射类型,如您在问题开头所述。 其他选项是单独的显式查询,用于为单个父项加载相关实体,或者为所有父项加载相关实体。

单亲的负载关系:

 context.Entry(event) .Collection(e => e.Discussions) .Query() .Where(d => ...) .Load(); 

为所有父项加载关系(需要关闭延迟加载):

 // load all parents var events = query.Where(e => ...).ToList(); // load child filtered by same condition for parents and new condition for children childQuery.Where(d => e.Event ... && d.Something ...).Load(); 

第二个解决方案要求child将导航属性返回给父级(用于构造最初用于加载父级的相同查询条件)。 如果您已正确配置所有内容并附加了实体,则EF应自动修复父实体中的关系(集合)(但它不会将动态代理中的集合标记为已加载,因此这就是您不能将此与延迟加载一起使用的原因)。