データベース優先シナリオでDbContextを使用すると、エンティティの追加と削除がObjectContextと比較して非常に遅いことがわかりました。 2000個のエンティティを追加し、最後に変更を保存すると、DbContextはObjectContextの3〜5倍遅くなります(ところで:大量のエンティティを追加する方がSqlBulkCopyを使用した方が良いことを知っていますが、それはポイントではありません)。追加するたびに変更を保存すると、DbContextの速度は2倍近く遅くなります。削除に関してはさらに悪化します。すべてのエンティティの削除の最後に保存すると、DbContextはObjectContextの約18倍遅くなります。
データベースアクセステクノロジーと小さなコンソールアプリケーションを比較してダブルチェックするために使用する、高度に開発されたテストアプリケーションを使用しました。どちらも、DbContextを使用してエンティティを追加および削除すると、悪い結果を示しました。コンソールアプリケーションの結果は次のとおりです。
Inserting 2000 entities via DbContext saving changes at the end: 2164ms
Inserting 2000 entities via ObjectContext saving changes at the end: 457ms
Inserting 2000 entities via DbContext saving changes after each object addition: 8420ms
Inserting 2000 entities via ObjectContext saving changes after each object adding: 4857ms
Inserting 2000 entities via DbContext using a new DbContext for each object addition: 4018ms
Deleting 2000 entities via DbContext saving changes at the end: 4794ms
Deleting 2000 entities via ObjectContext saving changes at the end: 261ms
Deleting 2000 entities via DbContext saving changes after each object deletion: 25536ms
Deleting 2000 entities via ObjectContext saving changes after each object deletion: 2110ms
VC 2010およびVS 11のEF 5.0 Beta 2でEF 4.3を使用して、ほぼ同じ結果を得ようとしました。 「EF#4.x DbContext Generator for C#」および「EF 5.x DbContext Generator for C#」。
何が間違っているのでしょうか?テスト結果によると、エンティティを追加または削除する必要のあるアプリケーションでDbContextを使用することはありません(残念ながらDbContextは使用できなくなります)。
Webサーバーにコンソールテストアプリケーションを配置します: EF 4.3 DbContext Test 、 EF 5.0 DbContext Test
どんなアイデア/修正も大歓迎です。
これをDbContextテストに追加してみてください:
dbContext.Configuration.AutoDetectChangesEnabled = false;
// Now do all your changes
dbContext.ChangeTracker.DetectChanges();
dbContext.SaveChanges();
そして、テストを再度実行してください。
コンテキストからAdd
、Attach
、またはDelete
を使用するたびにエンティティの変更をチェックするDbContext APIにアーキテクチャ上の変更がいくつかありました。 ObjectContext APIでは、SaveChanges
をトリガーしたときにのみこの検出が実行されます。最も一般的なシナリオではより良いソリューションですが、大量のデータ処理には特別な処理が必要です。
EF6では、 DbSet で AddRange および RemoveRange を使用できるようになりました。
リンクのドキュメントから:
AutoDetectChangesEnabledがtrue(デフォルト)に設定されている場合、エンティティを{追加、削除}する前にDetectChangesが1回呼び出され、再度呼び出されることはありません。これは、状況によっては、{Add、Remove} Rangeが{Add、Remove}を複数回呼び出すよりも大幅にパフォーマンスが向上する可能性があることを意味します。