WCF序列化循环引用时出错

本文关键字:出错 引用 循环 序列化 WCF | 更新日期: 2023-09-27 17:58:56

我试图返回引用了另一个对象的对象列表,反之亦然。

我只希望惰性加载得到"第一级子对象",我的意思是,如果我有一个带有"Place"属性的"Person"对象,我希望加载位置数据,但不是"Place"对象中的每个对象都需要加载。。。因为这将导致循环引用。。。

我已经读到,我可以通过在每个对象上使用[DataContract(IsReference=true)]来实现这一点。

我已经用这种装饰设置了模型中的每个对象(由EF自动生成),但在试图将其发送回服务调用方时仍然失败。

我遗漏了什么吗?提前谢谢。

WCF序列化循环引用时出错

我过去曾成功地使用[DataContract(IsReference=true)]来解决循环依赖性问题。诚然,它们不是EF生成的对象,但我不确定这有多重要。

确切的错误是什么?

是图表变大了吗?

可能是因为您的对象不是相同的实例,而是概念上相同类型的不同实例吗?

因此,当你的TypeA-instance1被序列化,并且它有一个对TypeB-instance1的引用,而TypeB-instance 1有一个对于TypeA-instance 1的引用时,两个实际的TypeA-stance1对象将不相等,这样序列化程序就不会试图重用引用了?

您可以覆盖对象上的equals方法,并根据对象的属性而不是将要使用的默认内存地址进行一些相等测试。

我的意思是,如果我有一个"人"对象对于"Place"属性,我想要放置要加载的数据,但不是每个"Place"中的对象需要已加载。。。

当使用延迟加载时,这是不可能的。一旦实体被序列化,序列化程序将访问每一个属性。访问每个导航属性将触发延迟加载,序列化程序将继续加载属性=>它将始终序列化完整的对象图。在你的场景中,它可能意味着:

  1. 序列化程序将从具有Place导航属性的Person开始
  2. 延迟加载将加载Place,并且序列化程序将进行序列化
  3. 如果Place具有所有Persons的导航属性,则延迟加载将触发并加载所有引用Place的人员
  4. 序列化程序将开始序列化每个加载的Person——如果IsReference设置为false,则对象图中会出现循环异常。否则,它将产生巨大的信息

这是一个非常基本的解释,若您在使用延迟加载时尝试序列化对象会发生什么。如果您的实体具有其他导航属性,则会对它们产生相同的效果。在最坏的情况下,您可以轻松地构建一个操作,该操作将尝试从数据库中提取并序列化所有数据。这很可能会导致超时。

懒惰加载还有一个问题。序列化发生在操作范围之外。因此,如果您在操作中关闭/处置ObjectContext,当实体触发延迟加载时,您将得到一个异常。

在WCF上公开实体时不要使用延迟加载,或者使用DTO来控制应该从操作传递哪些数据。

您可能需要将对象树转换为其他平面对象,然后返回这些对象。