1. 程式人生 > >Entity Framework 添加、附加、和實體狀態

Entity Framework 添加、附加、和實體狀態

鍵值 name 五個 能夠 att first 通過 數據集 attach

  這篇文章將會覆蓋如何新增和附加實體到上下文以及在 SaveChanges 中Entity Framework 如何處理它們。 Entity Framework 會在實體與上下文連接時追蹤它們的狀態,但你能在實體與上下文斷開連接或者 N-Tier 場景下讓 EF 知道你的實體的狀態是什麽。在這篇文章中展示的技術同時適用於 通過Code First 創建的模型 和 EF 設計器創建的模型 。 實體狀態 和 SaveChanges 在 EntityState 枚舉定義中,一個實體能夠處於以下的五個狀態之一。這些狀態是: 1、Added(新增的):實體將會被上下文追蹤但尚未持久化到數據庫中 2、Unchanged(未改變的):實體在數據庫中存在並且將會被上下文追蹤,但它的屬性值和數據庫中存在的值相比是尚未改變的(一致的) 3、Modified(已修改的):實體在數據庫中存在並且將會被上下文追蹤,同時它的部分或全部值已經被改變 4、Deleted(被刪除的):實體在數據庫中存在並且將會被上下文追蹤,但已經被標記為在下一次 SaveChanges 被調用時數據庫中將會刪除的部分 5、Detached(分離的):實體將不會被上下文追蹤 SaveChanges 在實體處於不同的狀態時做不同的事: 1、Unchanged 的實體不會被SaveChanges 提及到。當實體在Unchanged 狀態下,更新命令將不會被發送到數據庫。 2、Added 的實體在SaveChanges 結束時會被插入到數據中,並且在上下文中的狀態會變成 Unchanged 。 3、Modified 的實體在SaveChanges 結束時會被更新到數據庫中,並且在上下文中的狀態會變成 Unchanged 。 4、Deleted 的實體在SaveChanges 結束時會從數據庫中刪除,然後從當前上下文中分離,即 Detached。 下面的例子展示了實體的狀態和實體圖能夠被改變的方式 添加一個實體到上下文中
一個實體能在數據集中通過調用 Add 方法被添加到上下文中。這將會使實體處於Added 狀態,意味著它將在下次調用SaveChanges 方法時被插入到數據庫中,例如:
using (var context = new BloggingContext()) { var blog = new Blog { Name = "ADO.NET Blog" }; context.Blogs.Add(blog); context.SaveChanges(); }
另一種添加一個實體到上下文中的方式是改變它的狀態為 Added 。例如:
using (var context = new BloggingContext()) { var blog = new Blog { Name = "ADO.NET Blog" }; context.Entry(blog).State = EntityState.Added; context.SaveChanges(); }
最後,你也可以通過將一個實體掛勾到一個已被上下文追蹤的實體來添加它到上下文中。這可以通過將新實體添加到另一個實體的導航屬性集合中或著通過設置另一個實體的導航屬性引用指向新實體。例如:
using (var context = new BloggingContext()) { // 通過從已被追蹤的Blog中設置引用來新增一個新 User var blog = context.Blogs.Find(1); blog.Owner=new User{UserName="johndoe1987"}); //通過添加到一個已被追蹤的Blog中的集合中來新增一個新 User var blog = context.Blogs.Find(2); blog.Posts.Add(new Post{ Name ="How to Add Entities" }); context.SaveChanges(); }
註意以上所有的例子中,如果一個被新增的實體已關聯其他未被上下文追蹤的實體,這些新實體將會被新增到上下文中,並且會在下次調用SaveChanges 時插入到數據庫中。 附加一個已存在的實體到上下文中
如果你有一個已知的已在數據庫中存在但當前未被上下文追蹤的實體,你能通過在數據集上使用 Attach 方法來告知上下文去追蹤這個實體。這個實體將處於 Unchanged 狀態。例如:
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Blogs.Attach(existingBlog); // Do some more work… context.SaveChanges(); }
註意如果調用SaveChanges 時沒有對附加的實體進行其他的操作,那麽對數據庫將不會有任何的改變。這是因為這個實體處於Unchanged狀態下。 另一個附加已存在的實體到上下文中的方式是改變它的狀態為Unchanged。例如:
var existingBlog = new Blog { BlogId = 1,Name="ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Entry(existingBlog).State = EntityState.Unchanged; //Do some more work… context.SaveChanges(); }
註意在以上的例子中,如果被附加的實體已關聯其他尚未被追蹤的實體,那麽這些新實體也會被附加到以Unchanged的狀態附加到上下文中。
附加一個已存在但已被修改的實體到上下文中 如果你有一個已經在數據庫中存在並將會被改變的實體,你可以通過設置它的狀態為Modified 來告知上下文去附加這個實體。例如:
var existingBlog = new Blog {BlogId=1,Name="ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Entry(existingBlog).State = EntityState.Modified; //Do some more work… context.SaveChanges(); }
當你修改實體的狀態為 Modified 時,該實體的所有屬性將會被標識為已修改並所有的屬性值將會在SaveChanges被調用時發送到數據庫。 註意如果一個已被附加的實體已關聯其他尚未被追蹤的實體,那麽這些實體將會以Unchanged的狀體附加到上下文中——它們不會自動被修改。如果你有多個實體需要被標識為Modified ,你應該單獨設置每一個實體的狀態。 修改已被追蹤的實體的狀態 你可以在一個已被追蹤的實體進入上下文時通過設置它的狀態來直接修改狀態
var existingBlog = new Blog { BlogId = 1,Name = "ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Blogs.Attach(existingBlog); context.Entry(existingBlog).State = EntityState.Unchanged; //Do some more work… context.SaveChanges(); }
註意 為一個已被追蹤的實體調用 Add 或者 Attach 方法通常用來修改實體的狀態。例如,為一個已處於Added 狀態下的實體調用 Attach 方法會修改它的狀態為 Unchanged。 新增或者更新模式 一些應用程序中的一個常見的模式是根據主鍵的值來新增一個實體(導致數據庫插入)或者附加一個已存在的實體並標識其為已修改(導致數據庫更新)。例如,在使用數據庫自增整型作為主鍵時,通過識別主鍵是否為0來判斷一個實體是新實體還是已存在的是很常見的(實體的主鍵為0時視為新實體,主鍵非0時視為已存在)。這種模式能通過基於檢查主鍵值來設置實體狀態來實現。例如:
public void InsertOrUpdate(Blog blog) { using (var context = new BloggingContext()) { context.Entry(blog).State = blog.BlogId == 0 ? EntityState.Added : EntityState.Modified; context.SaveChanges(); } }
註意當你修改實體的狀態為 Modified 時,該實體的所有屬性將會被標識為已修改並所有的屬性值將會在SaveChanges被調用時發送到數據庫。 來源: https://msdn.microsoft.com/en-us/library/jj592676(v=vs.113).aspx

Entity Framework 添加、附加、和實體狀態