EF6 ленивая загрузка не работает, в то время как работа с загрузкой прекрасна

c# entity-framework-6

Вопрос

Я обновил приложение от EF4.1 до EF6, и теперь у меня проблема с ленивой загрузкой. Я использовал EF6.x DbContext Generator для генерации нового DbContext. Все советы из этой статьи также применяются.

  • Мои классы общедоступны
  • Не запечатан, а не абстрактно
  • Создать публичный конструктор
  • Не используйте ни IEntityWithChangeTracker ни IEntityWithRelationships
  • И ProxyCreationEnabled и LazyLoadingEnabled установлены в true
  • Свойства навигации виртуальны

Мне также кажется, что если я явно включу свойство навигации с Include("...") оно будет загружено.

Упрощенная версия моих POCOs и DbContext:

public partial class Ideation
{
    public Ideation()
    {

    }

    public long Id { get; set; }
    public Nullable<long> ChallengeId { get; set; }

    public virtual Challenge Challenge { get; set; }
}

public partial class Challenge
{
    public Challenge()
    {
        this.Ideations = new HashSet<Ideation>();
    }

    public long Id { get; set; }

    public virtual ICollection<Ideation> Ideations { get; set; }
}

public partial class BoxEntities : DbContext
{
    public TIBoxEntities()
        : base("name=BoxEntities")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Ideation> Ideations { get; set; }
    public virtual DbSet<Challenge> Challenges { get; set; }
}

Также я попытался установить ProxyCreationEnabled и LazyLoadingEnabled явно без везения. Сущность не загружается в качестве динамического прокси-сервера, поскольку этот снимок экрана отладки показывает:

Отлаживать

Что еще мне не хватает?

Принятый ответ

Ситуация, когда это может произойти, заключается в том, что сущность, которую вы пытаетесь загрузить с помощью Find , уже привязана к контексту как не-прокси-объект. Например:

using (var context = new MyContext())
{
    var ideation = new Ideation { Id = 1 }; // this is NOT a proxy
    context.Ideations.Attach(ideation);

    // other stuff maybe ...

    var anotherIdeation = context.Ideations.Find(1);
}

anotherIdeation будет не прокси-сервером, который уже подключен, и он не способен к ленивой загрузке. Это даже не помогло бы запустить запрос БД с var anotherIdeation = context.Ideations.SingleOrDefault(i => i.Id == 1); потому что опция слияния по умолчанию для запросов - AppendOnly , т. е. новый объект будет добавлен только в том случае, если к этому ключу уже нет прикрепленного объекта. Таким образом, anotherIdeation все равно будет не-прокси.

Вы можете проверить, прикреплен ли объект уже с помощью Local прежде чем вы вызываете Find в вашем методе GetById :

bool isIdeationAttached = context.Ideations.Local.Any(i => i.Id == id);

Популярные ответы

Комментарий Per @ ken2k, по умолчанию для новых моделей, начинающихся с EF 4, было включено по умолчанию ленивая загрузка. С EF 1 это было запрещено. Если вы перенесли свою модель с 1 на 4, она по умолчанию отключена. Вам нужно будет изменить контекст, чтобы включить это.

При этом вы указываете через отладку, что это правда. В этом случае проверьте свои сценарии использования. Возможно ли, что ваш контекст был удален до получения дочерних объектов. Обычно мы видим это, когда привязка данных к запросу LINQ, где контекст сконфигурирован в блоке «Использование», и фактическая итерация происходит не до тех пор, пока не пройдет область использования блока.




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему