В Entity Framework почему нет ленивой загрузки, работающей для свойства перехода от одного к ноль-другому?

Рассмотрим классы Person и Address, определенные как

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

где только некоторые лица имеют адрес, но у всех Адресов есть Лицо. Это отношение один к нулю или один, поэтому я настраиваю его как

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

Теперь, в моем коде, следующий подход (нетерпевая загрузка) работает отлично.

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

Однако, следующий подход (ленивая загрузка) не делает.

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

Кроме того, я подключил SQL Profiler, и я вижу, что EF даже не пытается ленить загрузить адрес во втором случае - он просто возвращает null.

Мне не удалось найти какую-либо документацию, в которой говорится, что EF не ленится загружать свойства навигации один-на-один-один-один. Это по дизайну, это ошибка, или я делаю что-то неправильно?

Я проверил это как с Entity Framework 5, так и с Entity Framework 6 Alpha 3 и получил те же результаты.

Ответы

Ответ 1

Я понял это. Классы сущностей должны быть объявлены как public, а свойства public virtual для ленивой загрузки работать. То есть.

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

Ответ 2

Другим моментом, который иногда может быть причиной, является то, что если вы забываете добавить виртуальный модификатор в свойство навигации

Ответ 3

Если вы используете первый подход к базе данных, убедитесь, что свойство Lazy Loading Enabled имеет значение True. Это свойство можно найти в свойствах диаграммы EDMX.

Вы также можете переопределить поведение, установив dbcontext.Configuration.LazyLoadingEnabled = true где dbcontext - это экземпляр DbContext.