WCF错误序列化循环引用

时间:2011-06-09 10:01:42

标签: c# silverlight wcf entity-framework

我正在尝试返回引用其他对象的对象列表,反之亦然。

我只想让延迟加载得到“第一级别的孩子”,我的意思是,如果我有一个带有“Place”属性的“Person”对象,我希望加载场所数据但不是“放置“对象需要加载......因为这将超前于循环引用...

我读过我可以在每个对象上使用[DataContract(IsReference = true)]来做到这一点。

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

我错过了什么吗?提前谢谢。

3 个答案:

答案 0 :(得分:5)

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

确切的错误是什么?

图表是否变大了?

可能是你的对象不是同一个实例,而是概念上相同类型的不同实例?

因此,当您的TypeA-instance1被序列化并且它具有对TypeB-instance1的引用时,它具有对TypeA-instance1的引用,2个实际的TypeA-instance1对象不能比较相等,所以序列化程序不会尝试重用引用?

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

答案 1 :(得分:4)

  

我的意思是,如果我有一个“人物”对象   有了“地方”的财产,我想要的   放置要加载的数据但不是每个   “Place”对象中的对象需要   加载...

使用延迟加载时无法做到这一点。一旦实体被序列化,序列化器将访问每个属性。访问每个导航属性将触发延迟加载,序列化程序将继续加载属性=>它将始终序列化完整的对象图。在您的方案中,它可能意味着:

  1. 序列化程序将以Person开头,其导航属性为Place
  2. 延迟加载将加载Place,序列化程序将序列化。
  3. 如果Place具有所有Persons延迟加载的导航属性,则会触发并加载引用Place的所有人员!
  4. 序列化程序将开始序列化每个加载的Person - 如果IsReference设置为false,您将在对象图中获得循环异常。如果不是,它将创造巨大的信息。
  5. 这是非常基本的解释,如果您在使用延迟加载时尝试序列化对象会发生什么。如果您的实体具有其他导航属性,则会对它们产生相同的效果。在最坏的情况下,您可以轻松地构建一个操作,该操作将尝试从数据库中提取和序列化所有数据。这很可能导致超时。

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

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

答案 2 :(得分:1)

您可能希望将对象树转换为其他平面对象并返回它们。