EF / LINQ如何在存在双向关系时包含子实体

时间:2012-10-02 11:37:52

标签: c# entity-framework linq-to-entities

环境

我在Framework 4.0上使用Entity Framework 5。 (这意味着我实际上使用的是EF 4.4)。 作为实体我使用STE(自我跟踪实体)因为我在N-Tier应用程序中工作。 我们使用数据库驱动的方法,因为EF是在游戏后期引入的。

上下文

我有2个实体,它们彼此都有导航属性。 (EntityA具有EntityB的导航属性,EntityB具有EntityA的导航属性)。 关系是' EntityA>一对多> EntityB&#39 ;.当我想通过LINQ表达式加载子实体时,我需要使用INCLUDE(S​​TE => Eager Loading),因为我将通过多个层传递所有数据。

代码

这是我的代码,用它的EntityB孩子调用EntityA。

using (var ctx = new MyEntities())
{
     var result = (from s in ctx.EntityA.Include("EntityB")
                   where s.Id = 11111
                   orderby s.TimeUpdated descending 
                   select s)
               .Take(10)
               .ToList();
     return result;
}

错误

  

System.StackOverflowException {无法计算表达式,因为   当前线程处于堆栈溢出状态。}

删除' INCLUDE'时没有错误。 我想原因很简单。我想加载带有子记录EntityB的EntityA,EntityB记录希望每次加载其父EntityA,以及EntityA ......我想每个人都理解这里的无限循环。

我的解决方案或替代方案

  • 我转到我的EDMX文件并删除EntityB中EntityA的导航属性。如果我现在想要加载有关EntityA的数据,而我有一个EntityB供我使用。我需要做一个单独的DB请求,我有两个不同的对象,我必须通过我的层传递。
  • 避免使用include,单独加载EntityA并将其推送到我的EntityB的导航属性中,该属性引用我的EntityA。

问题

在我的情况下,是否有更好的替代方法或方法来解决这个问题?我应该继续提出我提出的替代方案吗?因为我希望有一个更好,更清洁的解决方案。

我感谢你的时间

伊恩

3 个答案:

答案 0 :(得分:1)

我尝试在EF 5(Visual Studio 2012)中重现您的问题,但我没有收到任何错误。还有什么可能导致您的问题吗?它是否使用简单的POCO设置?

我还想注意,STE会给你带来很大的麻烦。我之前和STE一起工作过,现在我真的想避免它们。你确定要使用STE吗?

您可以使用普通的旧DTO,而不是使用STE。您将在服务器上保留富域模型,并仅向客户端发送必要的数据。通过这种方式,您可以为每个用例创建具有最少数据量的定制DTO。

答案 1 :(得分:0)

我来这里是对你说“你可以使用Include”,但显然在这种情况下它对你没有帮助。

正如我在互联网上阅读的那样,当我们怀疑(或有)一个无限循环的情况时,有一些变通方法:

  1. 我们可以使用foreach使用Load操作并手动加载子项。
  2. 我们可以自己创建一个数据库view that is a recursive query(并使用它的实体)。

答案 2 :(得分:0)

see this

但是我安装了更新4但仍然无法调试