En Entity Framework, ¿por qué la carga diferida no funciona para una propiedad de navegación de uno a cero o uno?

ef-code-first entity-framework entity-framework-5 entity-framework-6 lazy-loading

Pregunta

Considerar las clases de Person y Address definidas como

class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}

donde solo algunas personas tienen una dirección, pero todas las direcciones tienen una persona. Esta es una relación de uno a cero o uno , así que la configuro como

class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}

Ahora, en mi código, el siguiente enfoque (carga ansiosa) funciona perfectamente bien.

class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}

Sin embargo, el siguiente enfoque (carga perezosa) no lo hace.

class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}

Además, conecté el Analizador de SQL y puedo ver que EF ni siquiera intenta cargar la dirección de forma perezosa en el segundo caso, solo devuelve nulo.

No he podido localizar ninguna documentación que indique que EF no carga de forma perezosa las propiedades de navegación de uno a cero o uno. ¿Es esto por diseño, es un error, o estoy haciendo algo mal?

Probé esto con Entity Framework 5 y Entity Framework 6 Alpha 3 y obtuve los mismos resultados.

Respuesta aceptada

Me di cuenta de esto. Las clases de entidad deben declararse como public y las propiedades public virtual para que la carga diferida funcione. Es decir

public class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

public class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}

Respuesta popular

Otro punto que también puede ser la razón a veces, es si uno se olvida de agregar el modificador virtual a la propiedad de navegación




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué