非追跡セルフトラッキングエンティティを処理する適切な方法は何ですか?
-
21-09-2019 - |
質問
セルフトラッキングエンティティ。素晴らしい。
あなたがようなことをするときを除いて
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
次に、次のように推奨されるプラクティスをいくつか紹介します。 WCFシナリオでSTEを使用している場合、Steがサーバー側で次のように実装する変更トラッカーに依存する必要があります。
db.Users.ApplyChanges(user);
db.SaveChanges();
シナリオ2サーバー上にいる場合、推奨されるプラクティスは、EnableChangetrackingと呼ばれるObjectContextの部分クラスにメソッドを作成することです。このメソッドは、iObjectWithChangetrackerを実装し、変更追跡をオンにするため、変更されていない状態にあるエンティティをクエリします。
user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();
ここで、元々から取得された別のコンテキストからユーザーエンティティを保存してみてください
db2.users.ApplyChanges(user);
db2.SaveChanges();
シナリオ3サーバー側でユーザーエンティティを取得した同じオブジェクトコンテキストに接続されている場合、以下のような単純なPocoオブジェクトとしてSTEを使用します
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ユーザーエンティティが別のコンテキストから取得されている場合、コンテキストUはそれを使用して保存します。ここに、元のエンティティを取得する別のオプションがあります。
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/modificiange-self-tracking-entity-on-the-server.aspx
エンティティフレームワーク4.0レシピの本で、これらの概念を多くのシナリオで広範囲にカバーしています。