0

在尝试序列化 EF STE 对象图时,我回到了我之前写的关于 StackOverflowException的帖子中的“绘图板”......在未能成功调整 IIS7 中的堆栈大小后,如此所述,我决定去沿着寻找根本原因的道路...

我相信这与 EF 模型的设计方式有关。

简化后,我有一个父实体和一个子实体。Child 实体有两个返回给 Parent 的导航属性,例如 Child.Parent 和 Child.ParentUsed。自然地,父级有两个子级集合。

在仔细查看导致 StackOverflow 异常的数据后,我注意到这个对象图中有几个循环。我无法证明这一点,但我相当肯定循环导致了这个 StackOverflow 异常。

如果我删除数据库中这张表的数据,问题就会消失,但我将无法删除客户机器上的记录。不管设计是否糟糕,我必须以某种方式在 EF 级别解决这个问题。

我有什么选择来重做这个?如果我的 Child 对象没有返回父级的导航属性,而是有两个 int Fks,我想知道是否会有导致序列化阻塞的循环?有没有办法在一个实体上将导航属性更改为 Fks?

谢谢!

更新:

将子项的两个导航属性都移回父项可以解决此问题。我认为这不一定是周期问题,但也许堆栈已经用尽了试图检查引用并确定周期。

我不一定要删除导航属性。它们对客户端很有用。有没有更好的方法来解决这个问题?自定义序列化?

4

1 回答 1

1

当我使用 WCF 测试 EF 的性能时,我遇到了一个类似的问题。当查询的结果集超过 3000 个结果时,我得到了 StackOverflow。

如果您只消除其中一个导航属性,StackOverflow 就会消失。我将尝试解释循环发生的位置,但你们也可以尝试使用 DataContractSeriazer 将图形序列化到文件中,当您看到生成的 XML 时,您就会意识到出了什么问题。

每个对象只被序列化一次,但是序列化是深度优先的。以您的场景为例:

1 - 序列化 parent1

2 - 序列化 ChildList1 的第一个元素

3 - 现在我们正在序列化与 parent1 有关系的对象 Child1(已经序列化,因此使用了 Ref)。所以序列化 ParentUsed(一个不同的对象,parent2,与其他孩子有更多的关系) - 为 parent2 执行第 1 步

如果加载的父列表和关系的复杂性(记录之间)足够大,序列化器将尝试将所有图形序列化为第一个元素的“子”(递归)。将其中一个导航属性移回父级将消除循环,剩余的导航属性将始终引用已序列化的父级。

如果您只使用导航属性绑定到 UI,则可以使用多个 BindingSource(我习惯于 WinForms)和 FK 来建立关系并获得与导航属性相同的结果(尽管涉及更多工作)。

希望这可以帮助,

努诺佩雷拉

于 2012-07-09T21:44:12.977 回答