我有一个使用纯POCO实现的Entity Framework 4.0模型(没有代码生成,没有自我跟踪实体,只有普通的旧CLR对象).
现在,这是我在UI中执行更新的一些代码:
[HttpPost]
public ActionResult UpdatePerson(Person person)
{
repository.Attach(person);
unitOfWork.Commit();
}
本质上,我有一个Action方法接受一个强类型的Person对象,我需要UPDATE这个实体.
不出错,但也不会将更改保留到DB. 🙁
当我在工作单元的“提交”期间检查EntityState时:
var entities = ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
我看到我的实体,EntityState.Unchanged.
这就解释了为什么它没有坚持下去.我的查找,添加,删除操作正常工作(正确保持).但UPDATE似乎不起作用.
我发现一些线程说我需要手动设置对象状态:
ctx.ObjectStateManager.ChangeObjectState(person, EntityState.Modified);
那是对的吗?我会把这个逻辑放在哪里?作为我的工作单位的操作公开?
显然问题是我没有任何变化跟踪,因为使用了Pure POCO(没有EntityObject派生,没有INotifyPropertyChanging实现).
但直到现在我还没有发现它的问题.
我究竟做错了什么?
最佳答案 好吧,既然你没有任何改变跟踪等,那么当调用SaveChanges()时,EF应该有办法确定如何处理附加的实体.默认情况下,EntityState是Unchanged,因此如果要更新,则必须手动设置状态.
另一种方法是查询具有此Id的Person,使用从控制器获取的数据重写属性,并调用SaveChanges().实际上这是一种更安全的方式,因为您可以防止在用户编辑webform时删除Person的情况;但这显然需要额外往返DB,这通常不太理想.
在任何情况下,我都会有一个存储库Update()方法(比Attach更具体),它实际上会附加实体并将EntityState更改为Modified.你的Action中仍然有相对干净的代码:
public ActionResult UpdatePerson(Person person)
{
repository.Update(person);
unitOfWork.Commit();
}