搞不懂的EF CORE 实体追踪

这天小白又去面试了,回来告诉笔者面试问题都回答还不错,不过有个问题搞不懂,EF Core怎么还有个实体跟踪,还可以优化,一问这个当时就懵了。那么什么是EF Core的实体跟踪呢?这篇文章就替小白来回答一下。.

什么是EF Core实体追踪

    EF Core在数据库查询/修改/更新数据时,EF 上下文就会创建实体快照,对实体进行追踪。如果是修改或更新,当遇到savechangs时就会检测实体的更改,然后持久化到数据库。这是EF Core追踪实体的属性是否有改变的一种机制。

EF Core实体追踪可以优化吗?

    当我们只需要查询出实体而不需要修改时,实体追踪就没有任何用途了(需要深究)。这时可以调用 AsNoTracking 获取非追踪的数据,这样可以提高查询性能。代码如下:

  var rel= teamContext.Teams.AsNoTracking().ToList();  //teamContext是上下文,Teams是实体表

也可以全局设置上下文禁用和开启实体追踪。

 //置当前teamContext上下文查询不跟踪状态 teamContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; //置当前teamContext上下文查询跟踪状态 teamContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;

扩展知识

1、五种实体追踪状态
根据增删改的情况,EF Core实体追踪状态有五种,如下:
 
状态 说明
Detached  一切实体操作都是无效的
Unchanged 有关系,没有任何操作
Deleted 有关系,已经发出了删除的指令
Modified 有关系,已经发出了修改的指令
Added 有关系,已经发出了新增的指令   

我们可以根据EntityEntry类的State属性查询实体的当前状态。例如:

Team team=new Team{Name="张山"};//var state= teamContext.Entry(team).State;//DetachedteamContext.Add(team);state = teamContext.Entry(team).State;//AddedteamContext.SaveChanges();state = teamContext.Entry(team).State;//Unchanged
2、不查询修改数据
    通常我们修改数据的时候,需要查出数据然后再执行Savechanges把数据更新到数据库。我们可以根据跟踪设置更新字段的状态,这样就不需要再查一次了。如下
Team team2 = new Team {Id=3, Name = "李四" };var stateup = teamContext.Entry(team2);stateup.Property("Name").IsModified = true;teamContext.SaveChanges();
效果如下:
搞不懂的EF CORE 实体追踪
当然也可以设置删除状态去不查询删除数据,大家有兴趣试一试。
注意:这种方式的代码可读性、可维护性不强,并且使用不当有可能造成不容易发现的Bug。对性能提升不明显,不推荐使用,大家了解即可。
 
结语

    本文讲述了EF Core的实体追踪(也有叫实体跟踪),在面试的时候当问到EF Core优化的时候可以举例。希望本文对大家有所收获,同时欢迎大家留言讨论本文。