我是 Entity Framework 的新手,我使用的是 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 来更新实体。这是最好的方法吗?有没有什么方法可以通过传递实体而不首先找到它来更新实体?
这取决于您是否启用了自动跟踪。默认情况下,这意味着您检索的任何实体都将存储在您用来检索它的 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);//获取上下文中实体的条目
entry.State = EntityState.Modified;//告诉 Entity Framework 这个实体已经被修改
- 可选告诉 EF 您的实体上的哪些属性已被修改
- 调用 SaveChanges()