21

我发现的所有示例都引用了一个名为 ObjectContext 的类,该类在 CTP5 中似乎不存在。在这一点上我必须强调,CTP5 是我第一次接触实体框架。

我有一个已连接到我的 DbContext 的断开连接的 POCO。虽然 SaveChanges 没有接受更改,但我如何告诉我的上下文来更新该实体?

_context.Users.Attach(user);
// The user has been replaced.
_context.SaveChanges();
// The change is not saved.

我究竟做错了什么?

更新 12/01/2011 对大多数人来说可能很明显,但作为 EF 的第一次用户,我没有想到附加已经附加的对象会清除以前的状态。这给我带来了很大的痛苦。但是我想以一种非常通用的方式使用存储库模式,这种方式不关心对象是否已经附加或者是由于 ASP.NET MVC 绑定而新创建的。所以我需要一个UpdateUser方法,我附在下面。

    public User UpdateUser(User user) {
        if (_context.Entry(user).State == EntityState.Detached) {
            _context.Users.Attach(user);
            _context.Entry(user).State = EntityState.Modified;
        }
        return user;
    }

该方法显然假设对象以某种方式存在于数据存储中,UpdateUser毕竟它是被调用的。如果对象已附加,您将受益于对象的先前状态,这反过来将允许对 DB 进行优化更新。但是,如果没有附加对象,该方法会强制整个对象变脏。

现在看起来很明显,以前没有。希望它可以帮助某人。

富有的

4

3 回答 3

29

当您附加一个实体时,它会进入未更改状态(自从它附加到上下文后它没有被更改)。您只需将实体状态显式更改为Modified

_context.Users.Attach(user);
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
_context.SaveChanges();
于 2010-12-10T22:59:33.887 回答
4

为了完整起见,您可以通过将 DbContext 转换为 IObjectContextAdapter 来访问 ObjectContext:

((IObjectContextAdapter)context).ObjectContext.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);

Morteza 的方法更干净,得到了我的投票。

于 2010-12-20T01:22:44.533 回答
2

我相信你不需要在调用修改之前附加实体。只需设置为 modified 即可完成工作。

if (_context.Entry(user).State == EntityState.Detached)
{
    _context.Entry(user).State = EntityState.Modified;
}
于 2011-01-17T01:39:32.727 回答