#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’, поскольку у него нет первичного ключа. Могут отслеживаться только типы сущностей с первичными ключами. ‘