這節主要內容是經過不一樣的方法將離線實體附加到上下文中。html
在離線場景中,保存一個實體要略微困難一些。當咱們保存一個離線的實體圖集或一個單獨的離線實體時,咱們須要作兩件事。首先,咱們要把實體附加到新的上下文中,讓上下文了知道存在這些實體。其次,咱們須要手動設置每一個實體的EntityState,由於新的上下文不知道這些離線實體都通過了些什麼操做,因此新的上下文不能自動地給實體添加EntityState。數據庫
下圖說明了此過程。post
爲了將離線實體附加到上下文,併爲實體圖中的每一個實體設置EntityState,EF提供下邊幾種方法:spa
DbContext.Entry()方法返回一個指向特定實體的DbEntityEntry對象,這個DbEntityEntry對象提供有關實體實例的各類信息,咱們也能夠使用DbEntityEntry對象來操做實體。最重要的是,咱們能夠經過DbEntityEntry對象的state屬性來指定實體的EntityState以下所示:
context.Entry(entity).state = EntityState.Added/Modified/Deleted
一個栗子:3d
var student = new Student() { //Root entity (無主鍵值) StudentName = "Bill", StandardId = 1, Standard = new Standard() //Child entity (有主鍵值) { StandardId = 1, StandardName = "Grade 1" }, Courses = new List<Course>() { new Course(){ CourseName = "Machine Language" }, //Child entity (無主鍵值) new Course(){ CourseId = 2 } //Child entity (有主鍵值) } }; using (var context = new SchoolDBEntities()) { context.Entry(student).State = EntityState.Added; //context.ChangeTracker.Entities返回context追蹤的全部EntityEntry實例 foreach (var entity in context.ChangeTracker.Entries()){ Console.WriteLine("{0}: {1}", entity.Entity.GetType().Name, entity.State); } } //-----輸出: Student: Added Standard: Added Course: Added Course: Added
在上邊的栗子中,Student實體圖集包含了Standard和Course實體, context.Entry(student).State = EntityState.Added; 將父實體和子實體(不管有沒有主鍵值)的EntityState都設置成Added,因此咱們要謹慎使用Entry()方法。
下表說明Entry()方法的規則code
父實體 | 子實體 |
---|---|
Added | Added |
Modified | Unchanged |
Deleted | All child entities will be null |
DbSet.Add()方法將整個實體圖集附加到上下文中,同時把父實體和子實體的狀態都設置成Added
一個栗子:htm
//離線實體圖集 Student disconnectedStudent = new Student() { StudentName = "New Student" }; disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" }; using (var context = new SchoolDBEntities()) { context.Students.Add(disconnectedStudent); // 獲取EntityEntry實例用於查看實體的狀態 var studentEntry = context.Entry(disconnectedStudent); var addressEntry = context.Entry(disconnectedStudent.StudentAddress); Console.WriteLine("Student: {0}", studentEntry.State); Console.WriteLine("StudentAddress: {0}", addressEntry.State); } //輸出 Student: Added StudentAddress: Added
Dbset.Add()方法附加整個實體圖集到上下文中,全部實體的狀態都是Added,執行SaveChange()方法時會執行Insert操做,在數據庫添加新記錄。對象
DbSet.Attach()方法將實體圖集附加到一個新的上下文中,每一個實體的狀態都是Unchanged.
一個栗子:blog
//離線實體圖集 Student disconnectedStudent = new Student() { StudentName = "New Student" }; disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" }; using (var context = new SchoolDBEntities()) { context.Students.Attach(disconnectedStudent); // 獲取EntityEntry實例用於查看實體的狀態 var studentEntry = context.Entry(disconnectedStudent); var addressEntry = context.Entry(disconnectedStudent.StudentAddress); Console.WriteLine("Student: {0}",studentEntry.State); Console.WriteLine("StudentAddress: {0}",addressEntry.State); } //----輸出 Student: Unchanged StudentAddress: Unchanged
EF系列目錄連接:Entity Franmework系列教程彙總教程