Entity Framework使用EntityState和Attach來保存數據變化以及更新實體的個別字段
在使用Entity Framework作為ORM來存取數據的過程中,最常規的操作就是對數據對象的更新。本文將會包含如何Attach Entity到一個數據Context中,以及如何使用EntityState字段狀態來保存數據變化。
文本參考了如下兩篇文章:
https://msdn.microsoft.com/en-us/data/jj592676
https://stackoverflow.com/questions/30987806/dbset-attachentity-vs-dbcontext-entryentity-state-entitystate-modified
當要做數據更新時,我們通常會使用如下代碼:
1 context.Entity(entity).State = EntityState.Modified;
2 context.SaveChanges();
context.Entity(entity).State = EntityState.Modified; 這句代碼不僅會將entity attaching到當前的context中,而且還會告訴context這個entity已經發生了變化。當執行savechanges()時,EF會使用update語句將entity中所有的字段全部更新。
上面的這種方式雖然方便,但是在某些時候也會帶來效率上的浪費。如果我們只是想更新其中的某個或者某些字段而不是全部字段的時候,使用這種方式就不必要了。那麽該如何操作,才能讓Entity Framework精確的保存我們想要變更的字段呢?我們可以使用Dbset.Attach(entity)。
Dbset.Attach(entity)只是會將entity attach到context中,而不會告訴context這個實體已經發生修改。所以如果你只是attach entity而之後不做任何處理的話,savechanges()操作將不會有任何變化。所以它和context.Entity(entity).State = EntityState.Unchanged是相同的。要保存個別字段,需要將entity更改之後再調用savechanges方法。請參見下面的代碼樣例。
代碼樣例:
下面使我們定義的實體以及它們的Context:
1 public class Department2 { 3 public int Id {get;set;} 4 public string Name {get;set;} 5 public DateTime CreateTime {get;set;} 6 7 public int DepLeadID { get; set; } 8 9 [ForeignKey("DepLeadID")] 10 public DepLead Lead {get;set;} 11 }
1 public class DepLead 2 { 3 public int Id {get;set;} 4 public string name {get;set;} 5 public int age {get;set;} 6 }
1 public class Context : DbContext 2 { 3 public Context() : base("XXX") 4 { 5 } 6 public DbSet<Department> Departments { get; set; } 7 public DbSet<DepLead> DepLeads { get; set; } 8 9 protected override void OnModelCreating(DbModelBuilder modelBuilder) 10 { 11 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 12 } 13 14 }
如果我們使用如下方式更新數據:
context.Entity(someDepartment).State = EntityState.Modified;
context.SaveChanges();
那麽相當於執行如下SQL
UPDATE department
SET Name = ‘xxx‘,CreateTime = ‘XXX‘, DepLeadID = ‘XXX‘
where Id = ‘1000‘; -- the id of someDepartment
上面的這種方式,不會自動的檢查字段是否變化,而是把所有的字段全部按照someDepartment中的值進行更新,即使沒有任何變化。
而另外一種Attach的方式在更新上就會更加靈活。
context.Departments.Attach(someDepartment);
someDepartment.Name = ‘XXX‘;
context.SaveChanges();
以上片段會執行下面語句:
UPDATE department
set Name = ‘XXX‘
where Id = ‘1000‘
假如你想指定實體someDepartment中哪些字段是已經更改的狀態,可以按如下代碼:
context.Departments.Attach(someDepartment);
context.Entry(someDepartment).Property("Name").IsModified = true;
context.SaveChanges();
這樣它也會像上面的SQL那樣將Name字段更新。
Entity Framework使用EntityState和Attach來保存數據變化以及更新實體的個別字段