4

我有一个用纯 POCO 实现的 Entity Framework 4.0 模型(没有代码生成,没有自跟踪实体,只是普通的旧 CLR 对象)。

现在,这是我在 UI 中执行更新的一些代码:

[HttpPost]
public ActionResult UpdatePerson(Person person)
{
    repository.Attach(person);
    unitOfWork.Commit();
}

本质上,我有一个接受强类型 Person 对象的操作方法,我需要更新这个实体。

不会出错,但也不会将更改持久化到数据库中。:(

当我在工作单元的“提交”期间检查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 实现)。

但是直到现在我还没有发现它的问题。

我究竟做错了什么?

4

1 回答 1

2

好吧,由于您没有任何更改跟踪等,因此 EF 应该有一种方法可以确定在SaveChanges()调用附加实体时如何处理。默认情况下,EntityState 是 Unchanged,因此如果要更新,则必须手动设置状态。

另一种方法是Person使用此 ID 查询 ,使用从控制器获取的数据重写属性,然后调用SaveChanges(). 这实际上是一种更安全的方法,因为您可以保护自己免受用户在编辑 web 表单时删除 Person 的情况;但这显然需要额外的往返数据库,这通常是不可取的。

在任何情况下,我都会有一个存储库Update()方法(比 更具体),它实际上会Attach附加实体并将. 而且您的操作中仍然有相对干净的代码:EntityStateModified

public ActionResult UpdatePerson(Person person)
{
    repository.Update(person);
    unitOfWork.Commit();
}
于 2010-10-26T07:40:36.390 回答