为啥实体框架核心加载实体的关系而不添加包含
Posted
技术标签:
【中文标题】为啥实体框架核心加载实体的关系而不添加包含【英文标题】: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 命令中看到。您想强制或避免加载所有对象吗?看起来您使用包含强制执行,所有内容都已加载,然后您抱怨所有内容都已加载。
【参考方案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()...
【讨论】:
以上是关于为啥实体框架核心加载实体的关系而不添加包含的主要内容,如果未能解决你的问题,请参考以下文章
为啥向核心数据实体添加双重属性会导致远距离相关实体中的属性冲突出现 NSInternalInconsistencyException?