Ef核心LazyLoading - 类型集合的访问嵌套导航属性抛出DetachedLazyLoadingWarning错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ef核心LazyLoading - 类型集合的访问嵌套导航属性抛出DetachedLazyLoadingWarning错误相关的知识,希望对你有一定的参考价值。

我尝试使用ef core 2.1访问学生最新成绩的GradeInfo属性

我在问题的最后列出了模型

var students = applicationDbContext.Students.Where(s => s.Id ==2)
    .Select(student => new  
        LatestGrade = student.Grades.OrderBy(g => g.Date).FirstOrDefault(),
        Id = student.Id
        ).ToList();

另外我在startup.cs中使用延迟加载代理(来自Microsoft.EntityFrameworkCore.Proxies)

services.AddDbContext<ApplicationDbContext>(options => 
    options.UseLazyLoadingProxies()
           .UseSqlServer(connectionString));

抛出的错误是:

“为警告Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning生成错误:尝试在”GradeProxy“类型的分离实体上延迟加载导航属性”Info“。对于已加载的分离实体或实体,不支持Lazy-Loading 'AsNoTracking()'“。

另外,我想声明我尝试将Include添加到学生dbset中,如下面的代码所述,但问题没有解决。

var student = applicationDbContext.Students.Include( s => s.Grades )
                .ThenInclude( grade => grade.Info).Where(...).Select(...)

楷模

class Student
   public int Id  get; set;
   public virtual ICollection<Grade> Grades  get; set;

   ...


class Grade 
   public virtual GrandeInfo Info  get; set;
   public DateTime Date  get; set;


class GrandeInfo 
  public int Id  get; set;
  public int Score  get; set;

答案

对于此问题,它是由于如果您更改查询以使其不再返回查询开头的实体类型的实例,则会忽略包含运算符。你可以参考Ignored includes

而且,目前,不支持Include查询导航属性,请参阅Are .Include/.ThenInclude supposed to work with Select in RC1-final? #4641

要解决此问题,您需要查询db中的所有列,然后在客户端查询预期的类型。

var students = _context.Students
                    .Where(s => s.Id == 2)
                    .ToList()
                    .Select(student => new
                    
                        LatestGrade = student.Grades.OrderBy(g => g.Date).FirstOrDefault(),
                        Id = student.Id
                    )
                    .ToList();

以上是关于Ef核心LazyLoading - 类型集合的访问嵌套导航属性抛出DetachedLazyLoadingWarning错误的主要内容,如果未能解决你的问题,请参考以下文章

EF的三种数据加载方式

EF Core 2.1 中的 Eager loadingExplicit loading和LazyLoading (转自MSDN)

EF Core:如何访问多层封装的集合

无法访问已释放的上下文实例 EF 核心

无法使用自动映射器映射内部导航属性。 EF 核心

EF ChangeTracker 访问被跟踪实体及其导航集合