在实体框架中更新实体的最佳方法[重复]
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。 这是连接模式场景以上是关于在实体框架中更新实体的最佳方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章