Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 912
Mike Avatar asked May 08 '13 03:05

Mike


2 Answers

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; }
}
like image 149
Mike Avatar answered Sep 23 '22 09:09

Mike


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

like image 25
yoel halb Avatar answered Sep 23 '22 09:09

yoel halb