最近、5.0を使用してDbContextに4.1を使用してObjectContextからエンティティモデルを移動しました。 DbContextとObjectContextを使用してクエリのパフォーマンスが低下していることに気付いているので、後悔しています。テストシナリオは次のとおりです。DbContextクエリのパフォーマンスが悪いかどうかObjectContext
どちらのコンテキストも、約600個のテーブルで同じデータベースを使用します。 LazyLoadingとProxyCreationは両方ともオフになっています(コード例には表示されていません)。両方とも、事前生成されたビューを持っています。
このテストでは、まずメタデータワークスペースをロードするために1回の呼び出しが行われます。その後、100回実行されるforループでは、コンテキストを新規作成し、最初の10回を呼び出す呼び出しを行います(これはWCFサービスで使用されるため、forループ内にコンテキストを作成しています。コンテキスト毎回)
for (int i = 0; i < 100; i++)
{
using (MyEntities db = new MyEntities())
{
var a = db.MyObject.Take(10).ToList();
}
}
これをObjectContextで実行すると、約4.5秒かかります。 DbContextを使用して実行すると、約17秒かかります。 RedGateのパフォーマンスプロファイラを使用してこれをプロファイリングしました。 DbContextの場合、UpdateEntitySetMappingsというメソッドが主な原因です。これはすべてのクエリで呼び出され、メタスペースオブジェクトを取得し、OSpace内のすべてのアイテムを循環するように見えます。 AsNoTrackingは役に立たなかった。
EDIT:問題は、実際のクエリではなく、DbSetとObjectSetの作成\初期化と関係しています。 ObjectContextを使って呼び出しを行うと、ObjectSetを作成するのに平均42msかかる。 DbContextでコールすると、内部dbsetを作成するのに約140msかかります。 ObjectSetとDbSetの両方は、メタデータワークスペースからエンティティセットのマッピングルックアップを行います。私が気づいたのは、DbSetは、ObjectSetが動作していない間は、ワークスペース内のすべての型に対してDbSetを実行するということです。私は、パフォーマンスの差が少ない表が少ないモデルを推測している(試していない)。