web-dev-qa-db-ja.com

EF DBContextは接続を閉じないで破棄します

EF 6.1.0を使用しています

DBEntitesとして以下のカスタムDBContexオブジェクトがあります

public partial class DbEntities : DbContext
{
    public DbEntities()
        : base("name=DbEntities")
    {
        ////Configuration.LazyLoadingEnabled = true;
        ////Configuration.ProxyCreationEnabled = false;
    }

    //// I have ALL Entites added as below
    ////public virtual IDbSet<CCode> CCodes { get; set; }
}

コンテキストオブジェクトに対して以下の操作があります

using (var context = new DbEntities())
        {
            var entitySet = context.Set<T>();
            var res = entitySet.Where<T>(predicate).ToList();
            if (context.Database.Connection.State == ConnectionState.Open)
            {
                context.Database.Connection.Close();
            }

            return res;
        }

しかし、コンテキストオブジェクトを破棄した後も、アクティブなDB接続を確認できます。接続状態の条件では、接続がすでに閉じられていることがわかります(接続がtrueになったことはありませんでした)。

以下のクエリを使用して、SQLの接続を確認しています。

select db_name(dbid) , count(*) 'connections count'
from master..sysprocesses
where spid > 50 and spid != @@spid
group by db_name(dbid)
order by count(*) desc

以下のステートメントでは、SQL接続数が増加しています。しかし、処分した後でもそれは決してダウンしませんでした。 (つまり、ブロック実行後に接続を閉じることになっています)。

var res = entitySet.Where<T>(predicate).ToList();

どんな助けでも大歓迎です。

12
Chandra Mohan

コメントでわかったように、その理由は確かに.NETによって実行される接続プールです。 .NETは、パフォーマンス上の理由から、アプリケーションで使用するすべての接続文字列の接続のプールを維持します(接続の開閉は、多くの場合、パフォーマンスの点でコストがかかる可能性があるため)。そのプールには、特定の最小サイズと最大サイズがあります(MinPoolSizeおよびMaxPoolSize接続文字列パラメーターによって制御されます)。 (SqlConnection.Openを介して)接続を開くと、プールから取り出され、実際に新しく開かれることはありません。接続を閉じるとき(これもEFコンテキストを破棄することによって行われます)-代わりに接続がプールに入れられ、実際には閉じられない場合があります。接続が一定時間(約5分間)アイドル状態の場合-プールから削除される可能性があります。

何らかの理由でそれを避けたい場合は、接続文字列のMaxPoolSizeを0に設定するか、SqlConnection.ClearPoolまたはSqlConnection.ClearAllPoolsを使用して明示的にプールをクリアします。

16
Evk