【问题标题】:Best way to update an entity in entity Framework [duplicate]在实体框架中更新实体的最佳方法[重复]
【发布时间】:2015-05-10 01:19:35
【问题描述】:

我是实体框架的新手,我使用的是 Nhibernate。在 Nhibernate 中更新对象不需要传递 id,您只需传递实体,Nhibernate 自己匹配 id 并更新实体。在 EF 中,我使用这种方法:

        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 来更新实体。这是最好的方法吗?是否有某种方法可以通过传递实体而不首先找到它来更新实体?

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

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

    那么如果你编辑这个实体,当你调用DbContext.SaveChanges()时,EF会遍历你所有的实体,并与它们的原始值进行比较,如果有变化,它会执行一条更新语句。

    因此,如果您都检索实体、编辑它并想要保存它,所有这些都在同一个上下文的范围内。您所要做的就是致电contxt.SaveChanged(),EF 将确定该实体已更新。 (只要您没有禁用 AutoTracking)

    借用 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. 告诉DbContext此实体已被修改
    • var entry = context.Entry(entity); // Gets the entry for entity inside context
    • entry.State = EntityState.Modified; // Tell Entity Framework this entity has been modified
    1. 可选告诉 EF 您的实体上的哪些属性已被修改
    2. 调用 SaveChanges()

    【讨论】:

    • 很好的答案,谢谢。注意“将您的实体附加到DbContext”,正如您所说,您可以附加,但设置为已修改将为您附加; more info here
    【解决方案2】:

    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();
        }
    

    【讨论】:

    • 这与我使用的方法相同,从 db 获取对象然后对其进行修改。而且我没有第二步,您是说您必须指出哪些属性已更改。我只想通过更改传递实体,然后 EF 使用它的 id 获取对象,并对其进行修改。就像休眠一样。没有明确指定 id。
    • 这是连接模式场景
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    相关资源
    最近更新 更多