1. ホーム
  2. c#

[解決済み] EF 4.1のエンティティの挿入は、ObjectContextに比べてなぜそんなに遅いのですか?

2023-07-29 23:55:19

質問

基本的に、私は1つのトランザクション内で35000のオブジェクトを挿入します。

using(var uow = new MyContext()){
  for(int i = 1; i < 35000; i++) {
     var o = new MyObject()...;
     uow.MySet.Add(o);
  }
  uow.SaveChanges();
}

これには時間がかかる! もし私が基礎となる ObjectContex t を使用すると ( IObjectAdapter を使うことで)、まだ遅いですが20秒程度で終了します。見た目は DbSet<> が線形検索をしているようで、二乗の時間がかかっています...。

他にこの問題を見た人はいますか?

どのように解決するのですか?

コメントで Ladislav がすでに指摘しているように、パフォーマンスを向上させるには、自動変更検出を無効にする必要があります。

context.Configuration.AutoDetectChangesEnabled = false;

この変更検出は、デフォルトで DbContext API で有効になっています。

その理由は DbContext とは挙動が大きく異なる。 ObjectContext の API は、より多くの機能が DbContext API が呼び出すのは DetectChanges の関数よりも内部的に ObjectContext APIよりも内部的に優れています。

ここで を呼び出す関数のリストがあります。 DetectChanges をデフォルトで呼び出す関数の一覧があります。それらは

  • Add , Attach , Find , Local または Remove のメンバーは DbSet
  • GetValidationErrors , Entry または SaveChanges のメンバーは DbContext
  • Entries メソッドで DbChangeTracker

特に Add コール DetectChanges を呼び出し、これがパフォーマンスの低下の原因となっています。

これと対照的なのが ObjectContext のAPIコールは DetectChanges においてのみ自動的に SaveChanges のみであり AddObject といった、前述した対応するメソッドにはありません。そのため デフォルト の性能は ObjectContext の方が速いです。

なぜ、このデフォルトの自動変更検出を DbContext を導入したのでしょうか?よくわかりませんが、どうやらこれを無効にして DetectChanges を適切な箇所で手動で呼び出すことは 高度なものであり、アプリケーションに微妙なバグをもたらす可能性があるので、[it] は慎重に使用してください。 .