EntityFramework 学习 一 Update Entity Graph using DbContext:
使用主键属性
每个实体必须有主键
默认值的id属性值必须为0
在context2中,它不知道实体的状态,
只能通过实体的主键来判断实体的状态
如果主键为0,则是新的对象,不为0 就是修改
Standard disconnectedStandard = null; using (var context = new SchoolDBEntities()) { context.Configuration.ProxyCreationEnabled = false; disconnectedStandard = context.Standards.Where(s => s.StandardId == 58).Include(s => s.Teachers).FirstOrDefault<Standard>(); } //Update Standard in disconnected mode disconnectedStandard.StandardName = "Edited Standard Name"; //Update teachers collection by editing first teacher and adding new teacher disconnectedStandard.Teachers.ElementAt(0).TeacherName = "Edited Teacher Name"; disconnectedStandard.Teachers.Add(new Teacher() { TeacherName = "New Teacher", StandardId = disconnectedStandard.StandardId }); using (var newContext = new SchoolDBEntities()) { //mark standard based on StandardId newContext.Entry(disconnectedStandard).State = disconnectedStandard.StandardId == 0 ? EntityState.Added : EntityState.Modified; //mark teacher based on StandardId foreach (Teacher tchr in disconnectedStandard.Teachers) newContext.Entry(tchr).State = tchr.TeacherId == 0 ? EntityState.Added : EntityState.Modified; newContext.SaveChanges(); }
使用主键的好处有:
1.不需要多余的代码来决定实体的状态
2.良好的性能
不好的地方有 ;
1.每个实体都需要有主键,没有主键就不能确定实体的状态
2.不能决定unchanged状态的实体,如果实体没有改变也会被设置为modified状态,这就没必要去更新没有改变的实体
3.不能删除实体
方法2:
设置实体的State属性
首先,创建一个带有枚举参数的接口
interface IEntityObjectState { EntityObjectState ObjectState { get; set; } } public enum EntityObjectState { Added, Modified, Deleted, Unchanged }
其次,每个实体都实现该接口
public partial class Standard:IEntityObjectState { public Standard() { this.Students = new HashSet<Student>(); this.Teachers = new HashSet<Teacher>(); } public int StandardId { get; set; } public string StandardName { get; set; } public string Description { get; set; } public virtual ICollection<Student> Students { get; set; } public virtual ICollection<Teacher> Teachers { get; set; } [NotMapped] public EntityObjectState ObjectState { get; set; } } public partial class Teacher:IEntityObjectState { public Teacher() { this.Courses = new HashSet<Course>(); } public int TeacherId { get; set; } public string TeacherName { get; set; } public Nullable<int> StandardId { get; set; } public virtual ICollection<Course> Courses { get; set; } public virtual Standard Standard { get; set; } [NotMapped] public EntityObjectState ObjectState { get; set; } }
在客户端设置实体的状态
Teacher existingTeacher = null; using (var context = new SchoolDBEntities()) { context.Configuration.ProxyCreationEnabled = false; existingTeacher = context.Teachers.FirstOrDefault<Teacher>(); } Standard disconnectedStandard = new Standard() { StandardName = "New Standard", ObjectState = EntityObjectState.Added }; existingTeacher.ObjectState = EntityObjectState.Modified; //add existing teacher(in db) to standard disconnectedStandard.Teachers.Add(existingTeacher); //add new standard disconnectedStandard.Teachers.Add(new Teacher() { TeacherName = "New teacher", StandardId = disconnectedStandard.StandardId, ObjectState = EntityObjectState.Added });
using (var newContext = new SchoolDBEntities()) { //check the ObjectState property and mark appropriate EntityState if (disconnectedStandard.ObjectState == EntityObjectState.Added) newContext.Entry(disconnectedStandard).State = System.Data.Entity.EntityState.Added; else if (disconnectedStandard.ObjectState == EntityObjectState.Modified) newContext.Entry(disconnectedStandard).State =System.Data.Entity.EntityState.Modified; else if (disconnectedStandard.ObjectState == EntityObjectState.Deleted) newContext.Entry(disconnectedStandard).State = System.Data.Entity.EntityState.Deleted; else newContext.Entry(disconnectedStandard).State = System.Data.Entity.EntityState.Unchanged; //check the ObjectState property of each teacher and mark appropriate EntityState foreach (Teacher tchr in disconnectedStandard.Teachers) { if (tchr.ObjectState == EntityObjectState.Added) newContext.Entry(tchr).State = System.Data.Entity.EntityState.Added; else if (tchr.ObjectState == EntityObjectState.Modified) newContext.Entry(tchr).State = System.Data.Entity.EntityState.Modified; else if (tchr.ObjectState == EntityObjectState.Deleted) newContext.Entry(tchr).State = System.Data.Entity.EntityState.Deleted; else newContext.Entry(tchr).State = System.Data.Entity.EntityState.Unchanged; } //save changes newContext.SaveChanges(); }