【发布时间】:2013-02-06 22:30:08
【问题描述】:
我想找到一种使用 Linq 将导航属性过滤到相关实体子集的方法。我知道围绕这个主题的所有答案都建议使用匿名选择器,例如:
query.Where(x => x.Users.Any(y => y.ID == actingUser.ID))
.Select(x => new
{
Event = x,
Discussions = x.Discussions.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>())
})
.OrderBy(x => x.Discussions.Count())
.ThenBy(x => x.Event.Name);
但是,由于我们的查询生成的一般性质,这远不理想,并且如果您抛出分析器,也会产生非常可怕的 sql 查询。
我希望能够完成类似的事情:
query.Include(x => x.Discussions.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>()))
.OrderBy(x => x.Discussions.Count())
.ThenBy(x => x.Name);
我意识到这在 EF5(或任何版本)中不受支持,但必须有一种方法可以通过 Linq 完成对结果集的约束,而无需深入研究匿名类型选择语句。
我已经尝试过做一些事情:
query.GroupJoin(discquqery,
x => x.ID,
x => x.Event.ID,
(evt, disc) => evt.Discussions = disc.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>())).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 中约束连接非常简单,必须有一种方法通过 Linq 来完成。
PS:我已经搜索过 stack、MSDN、experts-exchange 等。请注意这不是重复的。任何甚至涉及到这个主题的东西要么有一个“无法完成”的答案,要么根本没有答案。没有什么是不可能的……包括这个。
【问题讨论】:
-
嗯,这是一个“可以做到”的答案:stackoverflow.com/a/13904825/861716
-
有一些方法可以扩展 EF 中的查询生成引擎。所以这不是不可能的,如果这是唯一的途径,那么答案是对 EF 查询引擎的扩展,以允许 INNER / OUTER JOIN 包含额外的过滤器。没有什么是不可能的......如果我必须重新编译 EF,那么我会......它没有现有的答案意味着答案是自己构建的(我目前甚至当我问这个问题时,计划这样做)
标签: c# linq entity-framework-5