EntityFramework Core 1.1方法理论详解
当我们利用EF Core查询数据库时如果我们不显式关闭变更追踪的话,此时实体是被追踪的,关于变更追踪我们下节再叙。就像我们之前在EF 6.x中讨论的那样,不建议手动关闭变更追踪,对于有些特殊情况下,关闭变更追踪可能会导致许多问题的发生。
实体状态
对于EF Core 1.1中依然有四种状态,有的人说不是有五种状态么,UnChanged、Added、Modified、Deleted、Detached。如果我们按照变更追踪来划分的话,实际上只有四种,将Detached排除在外,Detached不会被上下文所追踪。那么状态如何改变的呢?内部有一个IStateManager接口,通过此接口来对实体状态进行管理,此时再取决于SaveChanges被调用后背后是如何进行处理,我也就稍微看了下源码,深入的东西没去过多研究。
Added:实体还未插入到数据库当中,当调用SaveChanges后将修改其状态并将实体插入到数据库。
UnChanged:实体存在数据库中,但是在客户端未进行修改,当调用SaveChanges后将忽略。
Modified:实体存在数据库中,同时实体在客户端也进行了修改,当调用SaveChanges后将更改其状态并更新数据持久化到数据库。
Deleted:实体存在数据库中,当调用SaveChanges方法后将删除实体。
实体方法
在EF Core 1.1中依然存在Add、Attach、Update方法,我们通过上下文或者DbSet<TEntity>能够看到,当将实体传递到这些方法中时,它们与实体追踪可达图紧密联系在一起,比如说我们之前讨论的博客的导航属性文章的发表,当我们添加文章的发表的这个实体时,然后调用Add方法后此时文章的发表这个实体也就被添加。在EF 6.x中我们说过当我们调用Add等方法时EF内部机制将会自动调用DetectChanges,但是在EF Core 1.1中则不再调用DetectChanges方法。空口无凭,我下载了源码,如下:
public virtual void Add(TEntity item) { var entry = _stateManager.GetOrCreateEntry(item); if (entry.EntityState == EntityState.Deleted || entry.EntityState == EntityState.Detached) { OnCountPropertyChanging(); entry.SetEntityState(EntityState.Added); _count++; OnCollectionChanged(NotifyCollectionChangedAction.Add, item); OnCountPropertyChanged(); } }
上述我们没有看到任何自动调用DetectChanges的逻辑,在EF 6.x中我们讲到当调用SaveChanges时此时会回调DetectChanges,而在EF Core 1.1中同样也是如此,所以相对于EF 6.x而言,EF Core 1.1只是在SaveChanges时回调DetectChanges,在Add、Attacth、Update等方法则不再回调DetectChanges,这样的话性能就会好很多。我们看到源代码中调用SaveChanges时逻辑如下:
public virtual int SaveChanges(bool acceptAllChangesOnSuccess) { CheckDisposed(); TryDetectChanges(); try { return StateManager.SaveChanges(acceptAllChangesOnSuccess); } catch (Exception exception) {..} }EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解