6

大量のエンティティのコレクションを1つずつ再計算する必要があります。多くのクエリと同じ接続のオープン/クローズが多すぎる

このプロセス中、すべての自己追跡エンティティが同じObjectContext内で変更されます。処理が必要なエンティティごとに、少量のデータをデータベースからフェッチする必要があります。その結果、多くの同じSQLクエリが発生しますが、異なるパラメータが使用されます。

私はソリューションデザインのORM Profilerソフトウェアを使用して、データベースに送信されたクエリをプロファイルしています。

質問自体は大丈夫です。それらは短く、実行に多くの時間を要しません。

はしかし、私は、プロファイラは、クエリが実際にどのように処理されるかを私に示し方法については混乱しています:

enter image description here

あなたが見ることができるように、それは同じデータベース接続を開閉し続けます。これは、データベース接続の浪費時間を開閉するように見える

enter image description here

今、単一のオープン/クエリ/閉じる接続のための時間を見てみましょう。

this answerを読んだ後、私は今、それはこのようになります私のコードを変更:

using (var connection = new EntityConnection(ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString)) 
{ 
    using (var context = new MyEntities(connection)) 
    { 
     // ... 

私は今、それはまだ、まだ接続を(良い)と同じ接続を使用して、しかし、されていることが分かりますクエリ間で閉じて開き続けます。

Gert Arnold私は明示的にコンテキストを使用する前に接続を開くことをお勧めします。私はコードを次のように変更しました。

using (var connection = new EntityConnection(ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString)) 
{ 
    connection.Open(); 
    using (var context = new MyEntities(connection)) 
    { 
     // ... 

今すぐ動作します!すべてのクエリが同じデータベース接続に送信されます。

enter image description here

は、なぜ私は、コンテキストを使用する前に、接続を開く必要がないように私は今好奇心?

+0

これが重複ではありません。私は実際に同じ接続を再利用することができます。問題は、クエリ間で自身を開いたり閉じたりすることです。 –

+1

コンテキストを作成する前に接続を開いても閉じますか? (ところで、あなたのコードは完全に正しいとは思わない: 'new EntityConnection'を2回)。 –

+0

それは動作します!しかし、あなたが示唆したように、コンテキストを使用する前に明示的に接続を開いている場合に限ります。なぜなのかご存知ですか ? –

答えて

4

既存の接続でコンテキストを作成することは可能です。それについてのドキュメントを見つけるのは難しいですが、コンテキストがコンテキストを使用する前に明示的に開かれていれば、明示的に閉じたり破棄したりするまで開いています。私はEF5 ObjectContext(Linqpadコード)でこれを試験した:

using (var conn = new EntityConnection(connectionString)) 
{ 
    conn.Open(); 
    using (var db = new InventoryContext(conn)) 
    { 
     db.Products.ToList(); 
     conn.State.Dump(); 
     db.SaveChanges(); 
     conn.State.Dump(); 
    } 
} 

出力OpenOpenあります。接続が開かれていない場合、出力はClosed,Closedです。

+0

ありがとう!これは、コンテキストを使用する前に明示的に接続を開くことによって完全に動作します。結果を示すために質問を編集しました。 –

1

別の解決策は、DbContextが構築されたときに、接続をオープンすることができます

public partial class QueryModel : DbContext 
{ 
    public QueryModel(string connectionName):base(connectionName) 
    { 
     this.Database.Connection.Open(); 
    } 
}