In Entity Framework, why isn't lazy loading working for a one-to-zero-or-one navigation property?

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

Question

Consider Person and Address classes defined as

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; }
}

where only some Persons have an Address, but all Addresses have a Person. This is a one-to-zero-or-one relationship, so I configure it as

modelBuilder.Entity<Address>()
  .HasKey(a => a.PersonId)
  .HasRequired(a => a.Person)
  .WithOptional(a => a.Address);

Now, in my code the following approach (eager loading) works perfectly fine.

var person = context.Person
  .Include(a => a.Address)
  .Single(a => a.PersonId == 123);
var address = person.Address; // address != null (correct)

However, the following approach (lazy loading) does not.

var person = context.Person
  .Single(a => a.PersonId == 123);
var address = person.Address; // address == null (incorrect)

Moreover, I hooked up SQL Profiler and I can see that EF isn't even attempting to lazy load the Address in the second case--it just returns null.

I've been unable to locate any documentation that says EF does not lazy load one-to-zero-or-one navigation properties. Is this by design, is it a bug, or am I doing something wrong?

I tested this with both Entity Framework 5 and Entity Framework 6 Alpha 3 and obtained the same results.

Accepted Answer

I figured this one out. The entity classes must be declared as public and the properties public virtual for lazy loading to work. I.e.

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; }
}

Popular Answer

Another point that might also be the reason sometimes, is if one forgets to add the virtual modifier to the navigation property




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why