我正在使用EF 6.1.0
我在下面将自定义DBContex对象作为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; }
但是在放置上下文对象之后,我仍然可以看到一个活动的数据库连接。在连接状态下,我可以看到该连接已经关闭(该连接从未为真)。
我正在使用以下查询来查看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();
任何帮助将不胜感激。
正如评论中指出的那样,其原因确实是.NET执行的连接池。出于性能方面的原因,.NET会为您在应用程序中使用的每个连接字符串维护一个连接池(因为打开和关闭连接在性能方面通常可能会很昂贵)。该池具有一定的最小和最大大小(由MinPoolSize和MaxPoolSize连接字符串参数控制)。当您打开一个连接(通过SqlConnection.Open)时-它可能会从池中移出,而实际上并没有重新打开。当您关闭连接时(也可以通过布置EF上下文来完成)-连接可能会改为放入池中,并没有真正关闭。如果连接空闲了一定时间(大约5分钟),则可能会将其从池中删除。
MinPoolSize
MaxPoolSize
SqlConnection.Open
如果(出于某种原因)想要避免这种情况,可以将连接字符串的MaxPoolSize设置为0,或者通过SqlConnection.ClearPool或显式清除池SqlConnection.ClearAllPools。
SqlConnection.ClearPool
SqlConnection.ClearAllPools