Как использовать отложенную загрузку для DbQuery в ядре EF?

#c# #entity-framework-core #ef-core-2.2

#c# #entity-framework-core #ef-core-2.2

Вопрос:

Я использую отложенную загрузку для EF Core 2.2.3 с прокси, которые хорошо работают с наборами баз данных. Теперь мне нужно загрузить данные из представления SQL, и я использую DbQuery для этого. При попытке загрузить связанные данные для объекта, используемого в запросе, я получаю предупреждение detachedlazyloading:

Ошибка, сгенерированная для предупреждения «Microsoft.EntityFrameworkCore.Инфраструктура.DetachedLazyLoadingWarning: Была предпринята попытка отложенной загрузки навигационного свойства ‘ProjectStatus’ для отдельного объекта типа ‘ProjectProxy’. Отложенная загрузка не поддерживается для отдельных объектов или объектов, которые загружаются с помощью ‘AsNoTracking ()’.’. Это исключение можно подавить или зарегистрировать, передав идентификатор события ‘CoreEventId.Отключил lazyloadingwarning’ от метода ‘ConfigureWarnings’ в ‘DbContext.OnConfiguring’ или ‘AddDbContext’.

Я не использую AsNoTracking() нигде в своем коде.

DbQuery определяется в контексте OnModelCreating . Выдержка:

  modelBuilder.Query<ProjectView>()
                .ToQuery(() => Projects
                .Select(p => new ProjectView()
                {
                    Id = p.Id,
                    ProjectCategory = p.ProjectCategory,
                    ProjectPhase = p.ProjectStatus.ProjectPhase,
                }));
  

Projects является DbSet контекста.
Project.ProjectCategory это свойство NotMapped-Readonly-, которое использует отношение Project.ProjectStatus .

Свойства контекста:

 public virtual DbSet<Project> Projects { get; set; }
public virtual DbSet<ProjectStatus> ProjectStatus { get; set; }
public virtual DbQuery<ProjectView> ProjectViews { get; set; }
  

Выдержка из классов:

     public partial class Project
    {
            [NotMapped]
            public string ProjectCategory
            {
                get
                {
                    if (this.ProjectStatus == null)
                        return string.Empty;
                    var foo = "someweiredcalculations";

                    return foo
                }
            }
            public virtual ProjectStatus ProjectStatus { get; set; }
            public int ProjectStatusId { get; set; }
            public int Id { get; set; }

}

public class ProjectView
{
        public int Id { get; set; }
        public string ProjectCategory { get; set; }
        public string ProjectPhase { get; set; }
}

public partial class ProjectStatus : BaseEntity, IIdEntity<int>
    {

        public int Id { get; set; }
        public string ProjectPhase { get; set; }
        public virtual ICollection<Project> Projects { get; set; } = new HashSet<Project>();

    }
  

Как я могу заставить отложенную загрузку работать для этого DbQuery?

Большое вам спасибо.

Ответ №1:

Это просто своего рода ошибка (не нашел обходного пути, и проблема все еще открыта). Также прочитайте это. Как и советовали, и я цитирую

Обратите внимание, что предупреждение можно настроить так, чтобы оно не выдавалось с помощью ConfigureWarnings в DbContextOptionsBuilder.

Комментарии:

1. Как я уже писал, я не использую AsNoTracking() . При настройке options.ConfigureWarnings(warnings => warnings.Default(WarningBehavior.Ignore)); ошибка все еще возникает.

Ответ №2:

Похоже, это сделано специально, независимо от того.Используется AsNoTracking() или нет. Я не нашел никакой документации по этому вопросу.

Если вы застряли на .net core 2, единственным решением, которое я нашел, было загрузить связанные объекты в отдельный запрос. Эффективное прерывание отложенной загрузки.

Начиная с .net core 3 , это можно обойти, загрузив связанные свойства (.Include(x => x.ProjectStatus)) при использовании отложенной загрузки. Это было исправлено: https://github.com/aspnet/EntityFrameworkCore/issues/12780 . И сообщение об ошибке при использовании отложенной загрузки было изменено на: «Невозможно отследить экземпляр типа ‘FooQuery’, поскольку у него нет первичного ключа. Могут отслеживаться только типы сущностей с первичными ключами. ‘