4

セルフ トラッキング エンティティ。素晴らしい。

あなたが何かをするときを除いて

return Db.Users;

自己追跡エンティティは追跡されません (おそらく逆シリアル化されるまで)。

罰金。したがって、私たちに戻ってきたエンティティが追跡を有効にしていない可能性があることを認識する必要があります。

それで???

私が試したこと

指定されたメソッド本体の場合:

using (var db = new Database())
{
    if (update.ChangeTracker.ChangeTrackingEnabled)
        db.Configurations.ApplyChanges(update);
    else
        FigureItOut(update, db);

    db.SaveChanges();
    update.AcceptChanges();
}

次の実装はFigureItOutすべて失敗します。

db.Configurations.Attach(update);
db.DetectChanges();

または

db.Configurations.Attach(update);
db.Configurations.ApplyCurrentValues(update);

または

db.Configurations.Attach(update);
db.Configurations.ApplyOriginalValues(update);

または

db.Configurations.Attach(update);
db.Configurations.ApplyChanges(update

また、私がそれに投げかけることができると考えることができる他のことについても、

  1. データベースから元のエンティティを取得する
  2. 各プロパティを手で比較する
  3. 必要に応じてプロパティを更新する

正確には、自分自身を追跡していない自己追跡エンティティをどうすればよいのでしょうか??


小さな更新:

エンティティを変更済みとして盲目的にマークすることはできますが、これは少し臭いようです。この場合、私たちができる最善のことですか?

4

1 に答える 1

6

シナリオ1

従うべきいくつかの推奨される方法を次に示します。WCF シナリオで STE を使用している場合、STE が実装する変更トラッカーに依存する必要があるため、サーバー側で次のことを行います。

db.Users.ApplyChanges(user);
db.SaveChanges();

シナリオ 2 ただし、サーバー上にいる場合は、Objectcontext の部分クラスに EnableChangeTracking というメソッドを作成することをお勧めします。このメソッドは、IObjectWithChangeTracker を実装し、変更の追跡をオンにする、変更されていない状態のエンティティを照会します。

user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();

ここで、最初に取得された別のコンテキストからユーザー エンティティを保存しようとします。

db2.users.ApplyChanges(user);
db2.SaveChanges();

シナリオ 3 サーバー側で、ユーザー エンティティを取得したのと同じオブジェクト コンテキストに接続している場合、以下のように STE を単純な poco オブジェクトとして使用します。

user = db.users.first(u => u.userid == 1);
user.LastName = "XYZ";
db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
db.SaveChanges();

シナリオ 4 ユーザー エンティティが別のコンテキストから取得され、そのコンテキストを使用して保存する場合、エンティティを変更済みとしてマークし、何が変更されたかを気にしない別のオプションがあります。

user = db.users.first(u => u.userid == 1);
var db2 = new ObjectContext();
user.LastName = "XYZ";
db2.Users.Attach(user);
// i prefer this option..
db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified); 
db2.SaveChanges(); // updates all columns

シナリオ 5 ユーザー エンティティが別のコンテキストから取得された場合、コンテキストはそれを使用して保存します。元のエンティティを取得する別のオプションがあります。

user = db.users.first(u => u.userid == 1);
user.lastName ="XYZ";
var db2 = new ObjectContext();
db2.Users.First(u => u.userid == user.userid);
db2.users.ApplyCurrentValues(user);
db2.SaveChanges();

これは、いくつかのシナリオを説明するブログ投稿です。 http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modifying-self-tracking-entity-on-the-server.aspx

これらの概念については、私の Entity Framework 4.0 レシピ ブックで、多くのシナリオとともに詳しく説明しています。

于 2010-07-09T06:37:12.677 に答える