24

Soy bastante nuevo en el mundo ASP .NET MVC. Tal vez, esa es la razón por la que no puedo explicarme la causa de lo que es, para mí, un problema molesto.¿Por qué Entity Framework devuelve null List <> en lugar de los vacíos?

Tengo una clase con One-To-Many relashionship.

class MyClass{ 
    public List<OtherClass> otherClasses {get;set;} 
} 

Cuando estoy persistiendo una instancia de esta clase, lo lleno es la relación con una lista vacía <>

MyClass myClass = new MyClass(){ otherClasses = new List<OtherClass>() } 
context.myClass.Add(myClass); 

El problema es que, cuando intento para recuperar esa instancia, y por cualquier razón, intento acceder a esa lista, el sistema me da una excepción de referencia nula ...

Mi pregunta es: ¿por qué EF no devuelve listas vacías en lugar de nulas? Especialmente en este caso, ¿que lo estoy persistiendo con una lista vacía?

¿Hay alguna forma de evitar la verificación si las instancias son nulas?

+0

¿Cuál es su clase de infraestructura de entidades? –

Respuesta

21

Debería hacer que su entidad cree esas listas en el constructor. EF no crea colecciones dependientes, y espera que la entidad lo haga.

Por lo tanto, su caso, que haría que su entidad como esta:

class MyClass{ 
    public List<OtherClass> _otherClasses {get;set;} 

    public MyClass() { 
     _otherClasses = new List<OtherClass>(); 
    } 
} 
+0

Esto definitivamente resuelve mi problema! ¡Gracias por tu ayuda! Entonces, EF llama al constructor de objetos antes de cargarlo con la información persistente, ¿no? –

+0

No, EF no "llama" al constructor. C# lo hace. Cada vez que se crea un objeto, se llama al constructor.Incluso cuando EF materializa objetos desde el db. –

+0

¡Entendido! ¡Gracias! –

16

Haga que la colección otherClasses sea virtual. Esto permitirá a EF cargar la colección de forma perezosa.

class MyClass{ 
    public virtual List<OtherClass> otherClasses {get;set;} 
} 

De lo contrario, utilice la carga ansiosa con el método Include.

context.myClass.Include(m => m.otherClasses).SingleOrDefault(m => m.Id == foo); 
+1

De hecho, la carga diferida resuelve mi problema ... Pero trato de evitar la carga diferida porque me estaba dando Error de serialización de referencia circular cuando estaba usando solicitudes JSON. De todos modos, estoy contento de tu ayuda. ¡Gracias! –

+0

Para problemas de referencia circular, puede usar atributos como 'JsonIgnore' para evitar que una propiedad de navegación de retroceso se serialice. – Jess

0

lo tanto, si he entendido bien, está agregando un vacío List<OtherClass> al contexto y luego tratar de recuperarlo.

Supongo que tiene que pensar en cómo el contexto rastreará y consultará las entidades que se encuentran en su contexto. Esto generalmente lo hace el Key de la entidad. En su ejemplo, no le ha dado a la entidad un Key, por lo tanto, el contexto no tiene manejar en la entidad.

Por lo tanto, cuando consulta, el contexto no encuentra un objeto y devuelve nulo.

Si desea inicializar una nueva entidad, le recomendaría darle al menos un Key (generalmente la propiedad Id), y luego seleccione esa clave cuando la busque más adelante.

Espero que esto ayude.

+0

De hecho, mis clases reales tienen todas Atributo de ID. Fue solo un ejemplo en el que olvidé incluir la ID: P. De todos modos, gracias por tu respuesta! –

Cuestiones relacionadas