EF DBContext dispose未关闭连接

本文关键字:连接 DBContext dispose EF | 更新日期: 2023-09-27 18:15:43

我使用的是EF 6.1.0

我有以下自定义dbcontext对象作为DBEntites

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连接。在连接状态条件下,我可以看到连接已经关闭(连接从未为真)。

我使用下面的查询来查看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连接计数增加。但即使在处理后也没有放下。(我的意思是使用block执行后,它应该关闭连接)。

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

EF DBContext dispose未关闭连接

正如在评论中指出的那样,原因确实是。net执行的连接池。net为您在应用程序中使用的每个连接字符串维护一个连接池,这是出于性能原因(因为打开和关闭连接通常可能在性能方面代价高昂)。该池有一定的最小和最大大小(由MinPoolSizeMaxPoolSize连接字符串参数控制)。当你打开一个连接(通过SqlConnection.Open) -它可能会从池中取出,而不是真正重新打开。当您关闭连接(这也是通过处理EF上下文来完成的)时,连接可能会被放入池中,而不是真正关闭。当连接空闲一段时间(大约5分钟)-它可能会从池中删除。

如果你(出于某种原因)想要避免这种情况,你可以设置MaxPoolSize为0为您的连接字符串,或明确地清除池SqlConnection.ClearPoolSqlConnection.ClearAllPools

在这里注册一下我的经验。我对EF Core 6 + Postgres也有同样的问题,解决方案只是禁用"Pooling"

Pooling=false;