我有一个使用纯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();
}

09-30 19:39