【问题标题】:WCF error serializing cycle referenceWCF 错误序列化循环引用
【发布时间】:2011-06-09 10:01:41
【问题描述】:

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

我只希望延迟加载获取“第一级子项”,我的意思是,如果我有一个带有“Place”属性的“Person”对象,我希望加载地点数据,但不是“需要加载 Place" 对象...因为这会提前到循环引用...

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

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

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

【问题讨论】:

    标签: c# silverlight wcf entity-framework


    【解决方案1】:

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

    确切的错误是什么?

    是图表变大了吗?

    难道你的对象不是相同的实例,而是概念上相同类型的不同实例?

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

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

    【讨论】:

    • 嗯,这听起来很有趣。我的服务在尝试返回值时崩溃,而不是循环引用或我能理解的任何东西......我会看看这个。谢谢你的回答。
    • 您是否启用了日志记录?这可能会告诉您问题所在,或者至少让您看到正在发生的异常。
    • 在谷歌上对这个问题进行了长时间的搜索后,我必须说我的 DTO 类中的 [DataContract(IsReference=true)] 属性对我有用!
    【解决方案2】:

    我的意思是,如果我有一个“Person”对象 使用“Place”属性,我想要 放置要加载的数据,但不是每个 “放置”对象中的对象需要是 加载中...

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

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

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

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

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

    【讨论】:

    • 这都是真的。如果您不希望延迟加载一直加载所有实例,那么您可以将Place 实例替换为PlaceProxy,它实现了相同的接口,但只初始化了一些属性,其他没有操作.没有解决 OP 的问题,即为什么周期仍在发生(假设这确实是她的问题)。不过,您最好从服务中返回 DTO。然后问题就消失了。
    • 感谢您的回答。我以为我理解了这个问题,但现在更清楚了。我想我将创建自己的模型(几乎与我的 EF 模型相同),每个对象只有一些属性,并在返回之前加载它。你的意思是这个与DTO的?或者我应该为我找到的每个案例建立一个不同的类?谢谢!!
    • 是的,我的意思是模型。为每种情况创建不同的类也是可能的,但它引入了很多工作。它通常用于大型项目或优化传输数据量时。
    • 好的,非常感谢。我想避免这种情况,因为我有大量数据,我认为微软会提供任何解决方案;-)
    【解决方案3】:

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

    【讨论】:

    • 我已经考虑过这个选项,但我有一个庞大的数据模型,而且我认为我可以避免很多工作;-)。感谢您的回答,如果我最终解决此问题,我会将其标记为正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多