【Entity Framework】EF中SaveChanges如何使用
文章目錄
- 【Entity Framework】EF中SaveChanges如何使用
- 一、概述
- 二、更改跟蹤和SaveChanges
- 三、SaveChanges優勢
- 四、使用SaveChanges添加數據
- 五、使用SaveChanges更新數據
- 六、使用SaveChanges刪除數據
- 七、單個SaveChanges中的多個操作
- 八、備注
一、概述
雖然查詢允許從數據庫中讀取數據,但保存數據意味著向數據庫添加新實體,刪除實體或以某種方法修改現有實體的屬性。Entity Framework Core(EF Core)
支持將數據保存到數據庫。
二、更改跟蹤和SaveChanges
在許多情況下,程序需要查詢數據庫中的某些數據,對其執行一些修改,并保存這些修改;這有時稱為“工作單元”。下面示例展示我們修改的博客標題屬性。在EF中,這通常按如下方式完成:
using(var context = new BloggingContext())
{var blog = context.Blogs.Single(b=>b.Title=="工蟻網絡科技有限公司");blog.Title ="數字工蟻";context.SaveChanges();
}
上述代碼執行一下步驟:
- 它使用常規LINQ查詢從數據庫加載實例。默認情況下跟蹤EF的查詢,這意味著EF在其內部更改跟蹤中跟蹤加載的實體。
- 通過分配.NET屬性來照常操作加載的實體實例。此步驟不涉及EF。
- 最后調用
DbContext.SaveChanges()
。此時,EF會自動檢測任何更改,方法是將實體與加載實體時的快照進行比較。檢測到任何更改都將保存到數據庫;使用關系數據庫時,這通常涉及發送SQL
,UPDATE
來更新相關行。
請注意,上面描述了現有數據的典型更新操作,但添加和刪除實體時遵循類似的原則。通過調用DbSet<TEntity>.Add
和Remove
與EF的更改跟蹤器交互,從而跟蹤更改。然后,當調用SaveChanges()
時,EF會將所有跟蹤的更改應用于數據庫。
三、SaveChanges優勢
- 無需編寫代碼來跟蹤已更改的實體和屬性 - EF 會自動為你執行此操作,并且僅更新數據庫中的這些屬性,從而提高性能。 想象一下,如果加載的實體綁定到 UI 組件,允許用戶更改他們想要的任何屬性;EF 減輕了找出哪些實體和屬性實際已更改的負擔。
- 保存對數據庫的更改有時可能很復雜! 例如,如果要添加一個博客并為該博客添加一些帖子,則可能需要為插入的博客提取數據庫生成的密鑰,然后才能插入帖子(因為它們需要引用博客)。 EF 為你完成所有這些操作,從而消除了復雜性。
- EF 可以檢測并發問題。例如,當其他人在你的查詢和
SaveChanges()
之間修改了數據庫行時。并發沖突中提供了更多詳細信息。 - 在支持它的數據庫中,SaveChanges()自動包裝事務中的多個更改,確保在發生故障時數據保存一致。
- 在許多情況下,SaveChanges()還會對多個更改進行批處理,從而顯著減少數據庫往返次數并大幅提高性能。
四、使用SaveChanges添加數據
使用DbSet.Add方法添加實體類的新實例。調用DbContext.SaveChanges()
時,數據將插入到數據庫中:
using (var context = new BloggingContext())
{var blog = new Blog { Title = "數字工蟻" };context.Blogs.Add(blog);context.SaveChanges();
}
Add、Attach和Update方法全部呈現在傳遞給這些方法的實體的完整關系圖上。此外,還可以使用EntityEntry.State屬性僅設置單個實體的狀態。如:context.Entry(blog).State = EntityState.Modified
五、使用SaveChanges更新數據
EF 將自動檢測對由上下文跟蹤的現有實體所做的更改。 這包括從數據庫加載/查詢的實體,以及之前添加并保存到數據庫的實體。
只需修改分配給屬性的是值,然后調用SaveChanges
:
using(var context = new BloggingContext())
{var blog = context.Blogs.Single(b=>b.Title == "數字工蟻");blog.Title ="數字工蟻科技";context.SaveChanges();
}
六、使用SaveChanges刪除數據
使用DbSet<TEntity>.Remove
方法刪除實體類的實例:
using(var context = new BloggingContext())
{var blog = context.Blogs.Single(b => b.Title == "數字工蟻");context.Blogs.Remove(blog);context.SaveChanges();
}
如果實體已在于數據庫中,則將在SaveChanges
期間刪除該實體。如果實體尚未保存到數據庫,則在調用SaveChanges
時,會從上下文中刪除該實體其不再插入它。
七、單個SaveChanges中的多個操作
可以將多個添加/更新/移除操作合并到對 SaveChanges
的單個調用中:
using (var context = new BloggingContext())
{// seeding databasecontext.Blogs.Add(new Blog { Url = "Goyeer數字" });context.Blogs.Add(new Blog { Url = "數字工蟻" });context.SaveChanges();
}using (var context = new BloggingContext())
{// addcontext.Blogs.Add(new Blog { Url = "Goyeer數字工蟻" });context.Blogs.Add(new Blog { Url = "工蟻數字中國" });// updatevar firstBlog = context.Blogs.First();firstBlog.Url = "";// removevar lastBlog = context.Blogs.OrderBy(e => e.BlogId).Last();context.Blogs.Remove(lastBlog);context.SaveChanges();
}
八、備注
對于大多數數據庫提供程序,SaveChanges
是事務性的。這意味著所有操作要么成功要么失敗,絕不會部分應用這些操作。