我是如何解决Json序列化循环引用错误的?

时间:2011-01-21 00:55:18

标签: json entity-framework serialization

有帖子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中的导航属性有关,但之后我感到难过。感谢。

3 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:1)

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

您有几种方法:

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

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

答案 2 :(得分:-1)

快速注意:如果您仍然遇到异常,请记住摆脱

.Include("NestedObject")

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