消除EF 4 STE对象图中的循环

时间:2012-06-18 21:48:54

标签: c# wcf entity-framework entity-framework-4 self-tracking-entities

我回到了早先写过的关于StackOverflowException的post上的“绘图板”,同时尝试序列化EF STE对象图...在IIS7中未能成功调整堆栈大小之后描述here,我决定走上寻找根本原因的道路......

我认为这与EF模型的设计方式有关。

简化,我有一个Parent实体和一个Child实体。 Child实体有两个返回Parent的导航属性,例如Child.Parent和Child.ParentUsed。当然,父母有两个儿童收藏。

仔细观察导致StackOverflow异常的数据后,我注意到此对象图中有几个循环。我无法证明这一点,但我非常肯定这些周期导致了这个StackOverflow异常。

如果我在数据库中删除此表中的数据,问题就会消失,但我将无法删除客户计算机上的记录。不管设计与否,我不得不以某种方式解决这个问题。

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

谢谢!

更新

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

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

1 个答案:

答案 0 :(得分:1)

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

如果您消除只有一个导航属性,StackOverflow将会消失。我将尝试解释循环发生的位置,但您也可以尝试使用DataContractSeriazer将图形序列化为文件,并且在看到生成的XML时,您会发现错误。

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

1 - serialiaze parent1

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

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

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

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

希望这有帮助,

Nuno Pereira