这节主要内容是经过不一样的方法将离线实体附加到上下文中。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系列教程汇总教程