我是实体框架的新手,我正在使用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吗?有一些方法来更新实体只是在没有找到它的情况下传递实体吗?
答案 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
,则需要
DbContext
(如果您设置了EntityState.Modified
DbContext
此实体已被修改
var entry = context.Entry(entity); // Gets the entry for entity inside context
entry.State = EntryState.Modified; // Tell EF this entity has been modified
答案 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();
}