21

私が見つけたすべての例は、CTP5 には存在しないように見える ObjectContext というクラスを参照しています。この時点で強調しなければならないのは、CTP5 が Entity Framework に初めて触れたことです。

DbContext にアタッチした切断された POCO があります。ただし、SaveChanges は変更を取得しません。そのエンティティを更新するようにコンテキストに指示するにはどうすればよいですか?

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

私は何を間違っていますか?

2011 年 12 月 1 日更新 ほとんどの人にとって明らかかもしれませんが、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

エンティティをアタッチすると、変更されていない状態になります (コンテキストにアタッチされてから変更されていません)。Entity State を明示的に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

変更を呼び出す前に、エンティティをアタッチする必要はないと思います。単に変更に設定するだけでうまくいきます。

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