【问题标题】:How did I solve the Json serializing circular reference error?我如何解决 Json 序列化循环引用错误?
【发布时间】:2011-01-21 00:55:18
【问题描述】:

有帖子here 询问如何解决通过EF4 CTP5 返回序列化对象时的循环引用错误。不久前,我在 WCF Web 表单项目中遇到了同样的问题。

我能够在我的 WCF/Web 表单项目和我的 MVC3 项目中“解决”这个问题。我认为什么类型的项目并不重要,因为这似乎是一个 EF 序列化“东西”。

我通过在我的 ObjectContext 构造函数中禁用 ProxyCreation 解决了这个问题,如下所示:

public class MyObjectContext : DbContext, IDbContext
{
     public MyObjectContext(string connectionStringName) : base(connectionStringName)
     {
        ((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
     }
     public DbSet<Product> Products {get;set;}
     //etc.
} 

我的问题是:有人能解释一下为什么这似乎可以解决问题吗?

我认为问题与我的 POCO 中的导航属性有关,但在那之后我被难住了。谢谢。

【问题讨论】:

  • +1 只是因为你的标题让我笑了! :-)
  • 在这个地方你不能假装你知道你在说什么。最好说实话。感谢您的 +1。

标签: json entity-framework serialization


【解决方案1】:

如果您关闭代理创建,您也会关闭延迟加载。当实体发生序列化时,它会访问所有导航属性。如果启用延迟加载,它会加载所有相关对象并尝试序列化它们。它再次访问它们的所有属性,包括指向父对象的导航属性。此时你必须说这个属性是循环引用的序列化,否则它将再次序列化对象并继续无限循环。

这里的技巧可能是使用ScriptIgnore 属性注释子实体中的循环导航属性。

【讨论】:

  • 这很有意义。我认为它必须涉及延迟加载,但我没有意识到代理创建关闭了延迟加载。很好的答案!谢谢。
  • ScriptIgnore 不起作用,如果您禁用代理创建,它可能会起作用。
【解决方案2】:

发生循环引用是因为您在对象上使用了预加载。

你有几个方法:

  • 在加载查询(linq 或 lambda)时关闭即时加载 DbContext.Configuration.ProxyCreationEnabled = false;
  • 从 Domainmodel 中删除 virtual 关键字
  • 在加载对象时包含它们
  • 分离对象(= 没有预先加载功能和没有代理)
    • Repository.Detach(entityObject)
    • DbContext.Entry(entityObject).EntityState = EntityState.Detached
  • 克隆属性
    • 您可以使用 AutoMapper 之类的东西来克隆对象,不要使用 ICloneable 接口,因为它还会克隆对象中的 ProxyProperties,所以这不起作用。
  • 如果您正在构建 API,请尝试使用具有不同配置(不返回代理)的单独项目

PS。代理是 EF 从实体框架加载它时创建的对象。简而言之:这意味着它保存原始值和更新值,以便以后可以更新它们。它处理其他事情;-)

【讨论】:

    【解决方案3】:

    快速提示:如果您仍然面临异常,请记住摆脱

    .Include("NestedObject")

    这样父子关系也会消失,异常

    【讨论】:

      猜你喜欢
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-12
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      相关资源
      最近更新 更多