我正在寻找一种方法来使用where子句加载嵌套关系。
想象一下下面的查询示例。
select *
from directors d
inner join managers m
on d.id = m.director
inner join employees e
on m.id = e.manager
where e.name = 'John'
通过这样做很容易加载来自这些实体的所有信息:
ctx.Directors.Include(x => x.Managers.Select(y => y.Employees)).ToList();
但是如何在上面发布的查询中模拟我的where子句?
知道我使用的是Entity Framework 6,是否可以这样做?我已经研究过这个并没有找到我的问题的答案。
编辑1
我问这个,因为我试图在WCF Restful aplication中使用它。并且它以StackOverflowException返回,可能是因为我为实体构建了向后引用时的循环引用。
答案 0 :(得分:2)
从查看LINQ查询,这样的事情应该有效:
from director in ctx.Directors
from manager in director.Managers
from employee in manager.Employees
where employee.Name == "John"
select director;
答案 1 :(得分:2)
基本上,你应该考虑在另一个方向重新思考你的EF-Query(假设你有1:很多关系):
ctx.Employees
.Include(x => x.Manager.Director)
.Where(x => x.Name == "John")
.ToList();
然后,您有一份名为John的员工名单及其相关经理和董事。
从导演开始的问题是,您可以无条件地加载所有相关的管理器,或者您需要将结果选择到新的数据结构中,而不是使用默认的EF映射。
答案 2 :(得分:1)
作为使用导航属性的替代方法,您可以简单地在linq等效项中翻译您的SQL查询。 导航属性很棒但确保您确实需要它们。
var query = from director in ctx.Directors
join manager in ctx.Managers
on director.Id equals manager.DirectorId
join employee in ctx.Employees
on manager.Id equals employee.ManagerId
where employee.Name == "John"
select new
{
director,
manager,
employee,
};
此外,将您的查询投射到某种专用DTO上肯定会解决您的循环引用
修改强> 尽量不要直接序列化您的域,而是创建外部图层所需形状的视图模型。 如果您确实需要将实体暴露给外部世界,则可能需要关闭延迟加载。 事实上,关闭延迟加载仍然是Lazy loading and serialization don’t mix well