在实体框架中更新实体的最佳方法[重复]

Posted

技术标签:

【中文标题】在实体框架中更新实体的最佳方法[重复]【英文标题】: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 来更新实体。这是最好的方法吗?是否有某种方法可以通过传递实体而不首先找到它来更新实体?

【问题讨论】:

【参考方案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,则需要

    将您的实体附加到新的(或您当前的)DbContext (如果您设置 EntityState.Modified,这将自动为您完成) 告诉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
    可选告诉 EF 您的实体上的哪些属性已被修改 调用 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。 这是连接模式场景

以上是关于在实体框架中更新实体的最佳方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:多对多插入重复

从实体框架中删除重复的 Context.vb 文件

如何在实体框架查询中使用多表达式方法[重复]

实体框架核心存储库模式 - 重复检查

实体框架在播种数据库上插入重复项[重复]

实体框架理解[重复]