6

エンティティの大規模なコレクションの値を次々と再計算する必要があります。

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

Solutions Design の ORM Profilerソフトウェアを使用して、データベースに送信されるクエリをプロファイリングしています。

クエリ自体は私には問題ないようです。それらは短く、実行にそれほど時間はかかりません。

ただし、プロファイラーがクエリが実際にどのように処理されるかをどのように表示するかについて混乱しています。

ここに画像の説明を入力

ご覧のとおり、同じデータベース接続を開いたり閉じたりし続けます。

ここで、1 つの Open/Query/Close 接続の時間を見てみましょう。

ここに画像の説明を入力

データベース接続を開いたり閉じたりすると時間が無駄になるようです。

この回答を読んだ後、コードを変更したので、次のようになりました。

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))
    {
        // ...

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

ここに画像の説明を入力

コンテキストを使用する前に接続を開く必要があるのはなぜですか?

4

2 に答える 2

5

既存の接続を使用してコンテキストを作成することができます。それに関するドキュメントを見つけるのは難しいですが、コンテキストが使用する前に接続が明示的に開かれている場合、明示的に閉じられるか破棄されるまで開いたままになります。ObjectContextこれをEF5 (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です。

于 2013-05-14T18:44:48.847 に答える
1

DbContext別の解決策は、が構築されたときに接続を開くことです。

public partial class QueryModel : DbContext
{
    public QueryModel(string connectionName):base(connectionName)
    {
        this.Database.Connection.Open();
    }
}
于 2017-09-08T15:11:45.813 に答える