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