В 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.