13

Entity Frameworkに関するいくつかの記事 ( article1article2 ) を読んだことがありますが、それは DetectChanges を何度も呼び出すため、大量のデータを操作するときに非常に遅くなります。

たとえば、autoDetectChangesコンテキストを初期化するときに を無効にして、呼び出すDetectChanges()前に呼び出すことはでき.SaveChanges()ますか?

コンテキストは、挿入/変更/削除されたエンティティを認識しますか?

var _dbContext = new ProjectContext();
_dbContext.Configuration.AutoDetectChangesEnabled = false;

// add/edit/delete entities

_dbContext.ChangeTracker.DetectChanges();
_dbContext.SaveChanges();

このアプローチは機能するはずですか?または、隠れたバグを作成する可能性がありますか?

4

2 に答える 2

21

Arthur Vickersは、次のブログ投稿で、DetectChangesを呼び出す必要がない ( の前でなくてもSaveChanges)場合のルールを定義しています。

EF コードを呼び出しても、コンテキストは、以前に呼び出す必要がなかった場合に DetectChanges を呼び出す必要がある状態のままになります。

AddDeleteに関しては、 or を呼び出すAddか、 toまたはDeleteの状態を設定するため、これらは「EF コード」メソッドです。したがって、一連のエンティティをループして追加または削除するだけであれば、呼び出す必要はまったくありません。context.Entry(entity).StateAddedDeletedDetectChanges

編集に関しては、もう少し微妙だと思います。いずれかを使用してエンティティを更新すると...

context.Entry(entity).CurrentValues.SetValues(someObject);

...またはプロパティ API を使用してDbContext...

context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue;

...そして、これらは再び「EFコード」への呼び出しであるため、必要ありませんDetectChanges(前でも必要ありません)。SaveChanges

次のようなエンティティのプロパティ値を変更するだけの場合...

entity.SomeProperty = someValue;

...次に、上記のリンク先の同じブログ投稿の 2 番目のルールが適用されます。

非 EF コードがエンティティまたは複合オブジェクトのプロパティ値を変更するたびに、DetectChanges を呼び出す必要がある場合があります。

そして、いくつかのエンティティをループし、それらをコンテキストにロードまたはアタッチし、いくつかの (スカラーおよび複雑な) プロパティ値を変更するだけの場合DetectChanges、実際にはbeforeへの単一の呼び出しのみが必要だと思います。SaveChanges

より複雑なことを行う場合 (おそらく関係の変更? または他の何か?)、あなたのアプローチはもはや安全ではないかもしれません。

  1. AutoDetectChanges直前に一度だけ必要な場合は、そのままでは実装されず、多くの EF メソッドで呼び出されます。SaveChanges

  2. 同じブログ投稿で再び言及されています

    Add または Attach を呼び出すだけでなく、コードがエンティティのプロパティを変更する場合は、ルール 2 により、少なくとも SaveChanges の一部として、場合によってはその前に DetectChanges を呼び出す必要があります。

    (私からのハイライト)

DetectChanges残念ながら、直前よりも早い段階で呼び出す必要がある場合に表示されるコードの例はわかりませんSaveChanges。しかし、上記のポイント 1 のために、そのような例が存在すると確信しています。

于 2013-03-11T18:40:57.867 に答える