2011-01-21 7 views
12

Existe la publicación here que pregunta cómo resolver el error de referencia circular al devolver un objeto serializado a través de EF4 CTP5. Me encontré con este mismo problema hace un tiempo con un proyecto de formularios web de WCF.¿Cómo resolví el error de referencia circular de serialización de Json?

Pude "resolver" este problema en mi proyecto de formularios web/WCF y en mi proyecto MVC3. No creo que importe el tipo de proyecto, ya que parece ser una "cosa" de serialización EF.

He resuelto el problema mediante la desactivación de ProxyCreation en mi constructor ObjectContext así:

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

Mi pregunta es: ¿Puede alguien explicar por qué esto sería aparentemente resolver el problema?

Creo que el problema tiene que ver con las propiedades de navegación en mi POCO, pero después de eso estoy perplejo. Gracias.

+3

+1 ¡simplemente porque tu título me hizo sonreír! :-) –

+0

No puede fingir que sabe de lo que habla en este lugar. Mejor ser honesto Gracias por el +1. – trevorc

Respuesta

9

Si desactiva la creación de proxy, también desactiva la carga diferida. Cuando la serialización de la entidad ocupa, visita todas las propiedades de navegación. Si la carga diferida está habilitada, carga todos los objetos relacionados e intenta serializarlos también. De nuevo, visita todas sus propiedades, incluidas las propiedades de navegación que apuntan hacia el objeto principal. En este punto, debe decir serialización que esta propiedad es una referencia circular o serializará el objeto nuevamente y continuará en un ciclo infinito.

El truco aquí podría ser anotar su propiedad de navegación circular en la entidad hija con el atributo ScriptIgnore.

+0

Eso tiene perfecto sentido. Pensé que tenía que involucrar la carga diferida, pero no me di cuenta de que la creación del proxy desactivaba la carga diferida. ¡Gran respuesta! Gracias. – trevorc

+2

ScriptIgnore no funciona, podría funcionar si desactiva la creación de proxy resistente. – hazimdikenli

-1

nota rápida: si todavía se enfrentan a excepción recuerde deshacerse de

.Include("NestedObject")

De esta manera la relación entre padres e hijos se ha ido, así como la excepción

1

La referencia circular sucede porque usa ansiosa carga en el objeto.

usted tiene un par de métodos:

  • Desactive la carga ansiosa cuando su carga de la consulta (LINQ o lambda) DbContext.Configuration.ProxyCreationEnabled = false;
  • Retire la palabra clave virtual desde el modelo de dominio
  • ellos incluyen al cargar los objetos
  • Separar los objetos (= sin funcionalidad de carga ansiosa & sin proxy)
    • Repository.Detach (EntityObject)
    • DbContext. Entrada (EntityObject) .EntityState = EntityState.Detached
  • Clon las propiedades
    • Puede usar algo como AutoMapper para clonar el objeto, no use la interfaz ICloneable, porque también clona ProxyProperties en el objeto, por lo que no funcionará.
  • En caso de que usted está construyendo una API, trate de usar un proyecto grande separadas con una configuración diferente (que no devuelve proxies)

PS. Proxies es el objeto creado por EF cuando lo carga desde Entity Framework. En resumen: Significa que contiene los valores originales y los valores actualizados para que puedan actualizarse más tarde. Maneja otras cosas para ;-)

Cuestiones relacionadas