あなたの更新...
var f = db.Foos.First(x => someEqualityTest(foo));
f = foo;
...あなたがすべてでロードされたと添付オブジェクトf
を変更していないので、あなただけの分離オブジェクトfoo
で変数f
を上書き動作しません。添付されたオブジェクトはまだ文脈の中にありますが、ロード後に変更されておらず、変数を指していません。 SaveChanges
はこの場合何も行いません。
「標準オプションは、」あなたはしている:
var f = db.Foos.First(x => someEqualityTest(foo));
db.Entry(f).State = EntityState.Modified;
か、単に
db.Entry(foo).State = EntityState.Modified;
// attaches as Modified, no need to load f
これは修正されたすべてのプロパティをマークしていない - に関係なく、彼らが実際に変更された場合やない - とUPDATEを送信します各列ごとにデータベースに追加します。
修正としてだけは本当に変更されたプロパティをマークし、変更されただけの列に対してUPDATEを送信する第二の選択肢:今
var f = db.Foos.First(x => someEqualityTest(foo));
db.Entry(f).CurrentValues.SetValues(foo);
、200万オブジェクトとあなたは「標準を持っていない更新します両方のオプション、特に、ソースオブジェクトとターゲットオブジェクトのプロパティ名と一致するように内部的にリフレクションを使用する可能性のある2つ目のオプションが遅すぎる可能性があります。
更新のパフォーマンスに関する最良の選択肢は、変更追跡プロキシです。これは、エンティティクラスのすべてのプロパティをvirtual
(ナビゲーションプロパティだけでなくスカラープロパティ)としてマークする必要があり、変更追跡プロキシの作成を無効にしないことを意味します(デフォルトで有効)。
データベースからオブジェクトf
をロードすると、EFはレイジーローディングプロキシに似た動的プロキシオブジェクト(エンティティから派生したもの)を作成します。プロパティにはフラグが保持されるように各プロパティセッターにコードが注入されます変更されたかどうか。
プロキシによって提供される変更の追跡は、スナップショットベースの変更の追跡(SaveChanges
またはDetectChanges
で行われます)よりもはるかに高速です。
変更追跡プロキシを使用すると、上記の2つのオプションが高速であるとはわかりません。パフォーマンスに関する追跡プロキシを変更する真の選択肢は存在しないオブジェクトの数千と同様の更新状況で私の経験では
var f = db.Foos.First(x => someEqualityTest(foo));
f.Property1 = foo.Property1;
f.Property2 = foo.Property2;
// ...
f.PropertyN = foo.PropertyN;
:あなたが最高のパフォーマンスを得るために、手動プロパティの割り当てを必要とすることも可能です。
はあなたがチェック方法についての少しより多くの光を当てることができれば2つのインスタンスのフーは等しいですか?単純なIDの比較ですか? –
私はちょうど詳細を一般化しようとしていましたが、ソリューションのより大きな論理的側面に焦点を当てました – Didaxis