在实体框架中更新实体的最佳方式

Die*_*nue 3 c# entity-framework

我是实体框架的新手,我正在使用Nhibernate.在Nhibernate更新对象时,传递id不是必需的,你只需传递实体,Nhibernate就自己匹配id并更新实体.在EF我正在使用这个aprouch:

        protected virtual bool UpdateEntity(TEntity entity, int id)
        {
          using (var ctx = new GenericContext())
          {
              var list = ctx.Set<TEntity>().ToList();
              ctx.Entry<TEntity>(ctx.Set<TEntity>  ().Find(id)).CurrentValues.SetValues(entity);
              return ctx.SaveChanges() > 0;
        }
       }
Run Code Online (Sandbox Code Playgroud)

这需要id来更新实体.这是最好的aprouch吗?有一些方法来更新实体只是在没有找到它的情况下传递实体?

Mic*_*han 8

这取决于您是否启用了自动跟踪.默认情况下,这意味着您检索的任何实体都将存储在DbContext您用于检索它的实体中,以及其原始值的副本.

然后,如果您编辑此实体,当您调用时DbContext.SaveChanges(),EF将遍历您的所有实体,并将它们与原始值进行比较,如果有任何更改,它将执行更新语句.

因此,如果您同时检索实体,编辑它,并希望保存它,则所有这些都在同一上下文的范围内.所有你需要做的就是打电话contxt.SaveChanged(),EF会知道这个实体已经更新了.(只要你没有禁用自动跟踪)

借用Eriks代码:

var ctx = new SchoolDBEntities() 

var student = ctx.Students.Where(s => s.Name == "John Doe").First();    

student.Name = "Erik Blessman";

ctx.SaveChanges(); // Will update the  student
Run Code Online (Sandbox Code Playgroud)

否则,如果此实体是手动创建的,并且不属于DbContexts您需要的任何实体

  1. 将您的实体附加到新的(或您当前的)DbContext (如果您设置,将自动为您完成EntityState.Modified)
  2. 告诉DbContext这个实体已被修改过
    • var entry = context.Entry(entity); // Gets the entry for entity inside context
    • entry.State = EntryState.Modified; // Tell EF this entity has been modified
  3. (可选)告知EF您的实体上的哪些属性已被修改
  4. 调用SaveChanges()


Eri*_*man 5

http://www.entityframeworktutorial.net/EntityFramework4.3/update-entity-using-dbcontext.aspx

    Student stud;
    //1. Get student from DB
    using (var ctx = new SchoolDBEntities())
    {
        stud = ctx.Students.Where(s => s.StudentName == "New Student1").FirstOrDefault<Student>();
    }

    //2. change student name in disconnected mode (out of ctx scope)
    if (stud != null)
    {
        stud.StudentName = "Updated Student1";
    }

    //save modified entity using new Context
    using (var dbCtx = new SchoolDBEntities())
    {
        //3. Mark entity as modified
        dbCtx.Entry(stud).State = System.Data.Entity.EntityState.Modified;     

        //4. call SaveChanges
        dbCtx.SaveChanges();
    }
Run Code Online (Sandbox Code Playgroud)