【问题标题】:Why is Entity Framework core loading entity's relations without adding include为什么实体框架核心加载实体的关系而不添加包含
【发布时间】:2020-02-17 05:34:36
【问题描述】:

我在 .net 核心项目中使用 EF 核心。从 ef 上下文中获取数据后,对象的实体(一对多等)会自动加载。

这是我的代码:

 public TimeSheetActivity Get(int id)
 {
     DataSets.TimeSheetActivity dbActivity = db.TimeSheetActivities
                                               .Include(k => k.ProjectFile)
                                               .Include(k => k.MeasurementUnit)
                                               .Include(k => k.TypeOfWork)
                                               .Include(k => k.TimeSheetProject)
                                               .FirstOrDefault(k => k.ID == id);

     return dbActivity == null ? null : _mapper.Map<TimeSheetActivity>(dbActivity);
 }


public Project GetActivityProject(int id)
{
    //db.SaveChanges();

    TimeSheetActivity activity = Get(id);

    if (activity == null)
    {
        return null;
    }

    var dbTimeSheetProject = db.TimeSheetProjects.First(k => k.ID == activity.TimeSheetProjectId);

    var dbProject = db.Projects.First(k => k.ID == dbTimeSheetProject.ProjectId);
    // PROBLEM HERE >> dbProject is loading all entities related
    return _mapper.Map<Project>(dbProject);
}

问题在上面标记并在Projects上下文中注释,这里是项目类:

public class Project
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public DateTime DateAdded { get; set; }

        public int? ParentId { get; set; }
        public int? DepartmentId { get; set; }
        public int? CompanyId { get; set; }


        public virtual Department Department { get; set; }
        public virtual Company Company { get; set; }

        public virtual Project Parent { get; set; }

        public virtual List<Project> Activities { get; set; }
        public virtual List<TimeSheetProject> TimeSheetProjects { get; set; }
        public virtual List<ProjectFile> ProjectFiles { get; set; }

    }

调试捕获:

【问题讨论】:

  • 在这种情况下,您不能依赖监视窗口。东西是按需加载的,观看它是一种需求。因此,无法查看是否加载了某些内容。如果您想确定,最好检查发送到 SQL-Server 的查询,以查看包含的内容。
  • 当你使用virtual 关键字表示EF load company LazyLoad
  • @Holger 我在编译代码行后加载手表,所以它会产生实际的 db 对象结果。另外,automapper 抛出异常,因为它无法转换所有填充的实体..
  • @AmirNorouzpour 我删除了 virtual 关键字,没有任何改变
  • 不,不可能查看任何“实际的数据库结果”,监视窗口本身正在向您的数据库发送进一步的查询,并重新加载您想查看的所有内容。即使这样,您“中断所有线程”调试窗口也可以运行您的代码。如果对象是在一个查询(使用包含)或多个查询(使用延迟加载)中加载的,您只能在 SQL 命令中看到。您想强制或避免加载所有对象吗?看起来您使用包含强制执行,所有内容都已加载,然后您抱怨所有内容都已加载。

标签: c# entity-framework linq asp.net-core entity-framework-core


【解决方案1】:

我认为问题是这样的(摘自文档):

Entity Framework Core 将自动修复先前加载到上下文实例中的任何其他实体的导航属性。因此,即使您没有明确包含导航属性的数据,如果之前加载了部分或所有相关实体,该属性仍可能会被填充。

https://docs.microsoft.com/en-us/ef/core/querying/related-data#eager-loading

【讨论】:

  • 这可能是个有趣的案例
  • 感谢您指出问题,我通过添加额外的 linq 表达式 asNoTracking() 来修复它
【解决方案2】:

关于@cristi71000 的回答,情况就是这样。我的解决方案是添加AsNoTracking() 如下:

var dbProject = db.Projects.AsNoTracking()...

【讨论】:

    猜你喜欢
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多