【问题标题】:EF/LINQ How to include child entities when there is a bidirectional relationEF/LINQ 存在双向关系时如何包含子实体
【发布时间】:2012-10-02 11:37:52
【问题描述】:

环境

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

上下文

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

代码

这是我调用 EntityA 及其 EntityB 子级的代码。

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 {无法评估表达式,因为 当前线程处于堆栈溢出状态。}

删除“包含”时没有错误。 我想原因很简单。我想用子记录EntityB加载EntityA,EntityB记录每次都想加载它的父EntityA,而EntityA……我想每个人都明白这里的无限循环。

我的解决方案或替代方案

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

问题

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

感谢您的宝贵时间

伊恩

【问题讨论】:

  • +1 为您提出一个非常好的(第一个)问题。
  • 我尝试在 EF 5 (Visual Studio 2012) 中重现您的问题,但没有收到任何错误。还有什么可能导致您的问题吗?它是否适用于简单的 POCO 设置? (旁注..我以前与 STE 合作过,现在我真的想避免它们。您确定要使用 STE 吗?)
  • 我也无法重现该错误(EF5、.NET 4.0)。是否可以发布堆栈跟踪并将敏感数据清空?
  • 好的,我接下来发现:我的项目是一个 Webapp。当我在 PC 上本地运行 Webapp 并调用该方法时,会引发此错误。当我从测试类运行完全相同的方法时,不会引发错误。但是当 webapp 抛出错误时,我可以通过删除“包含”来修复它,所以我认为错误必须在这一行中。除了 '在 mscorlib.dll 中发生'System.StackOverflowException' 类型的未处理异常'之外,我没有更多堆栈跟踪。
  • @WouterdeKort : 因为我被 N 层设计卡住了,我不能使用其他类型

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


【解决方案1】:

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

我还想指出,STE 会让您非常头疼。我以前曾与 STE 合作过,现在我真的很想避免他们。您确定要使用 STE 吗?

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

【讨论】:

    【解决方案2】:

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

    正如我通常在互联网上看到的,当我们怀疑(或有)无限循环的情况时,有一些解决方法:

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

    【讨论】:

    • - 1. 无法应用加载操作,因为我的导航属性不是 EntityCollections 而是 TrackableCollection - 2.可悲的是,这不适用于我的上下文。例如,我想轻松访问父实体 (EntityA) 并将其保存为我的 EntityB 的字段。我测试了 'context.LoadProperty(EntityB, "EntityA")' 但也生成了相同的 StackOverflowException。感谢您的提示
    【解决方案3】:

    see this

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 2015-09-06
      相关资源
      最近更新 更多