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

时间:2015-03-08 22:23:27

标签: 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;
        }
       }

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

2 个答案:

答案 0 :(得分:7)

这取决于您是否启用了自动跟踪功能。默认情况下,这意味着您检索的任何实体都将存储在您用于检索它的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

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

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

答案 1 :(得分: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();
    }