EntityFramework 保持连接打开?

EntityFramework keeping connections open?

我遇到了一个问题,原因是我的应用程序通过 EF 连接到数据库,但在我不希望它们打开时打开了。我正在为体育赛事做一个计时系统并即时创建新数据库,复制现有的数据库文件并使用根据需要使用正确的文件名构建的连接字符串附加它们。

创建新文件的一种方法是将其基于现有事件,即复制然后清除大量数据。如果我在加载现有事件时尝试此操作,我无法复制该文件,因为 SQL 服务器已将其锁定,而且我无法明确分离它,因为 SQL 服务器声称它正在使用中。当我查看 sys.sysprocesses 的内容时,我发现是的,EF 正在维护 "AWAITING COMMAND." 的连接 尽管我将所有内容包装在 using() 结构中并使用 IDbConnectionInterceptor 来确认我的连接是正在处理。

我已经设法将示例分解为

using (SportsTimerEntities ctx = new SportsTimerEntities("metadata=res://*/DataModel.csdl|res://*/DataModel.ssdl|res://*/DataModel.msl;provider=System.Data.SqlClient;provider connection string=\"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Work\SportsTimer\Events\559eae6a-9974-4463-8546-00824b4aad23.mdf;Integrated Security=True;MultipleActiveResultSets=True;Connect Timeout=30;Application Name=EntityFramework\""))
            {
                dbDevices = ctx.Devices.ToList();
            }

using() 块之前没有连接。块退出后,连接仍然存在。尽管 IDbConnectionInterceptor 确认 Dispose() 已被调用。

目前我能想到的释放文件的唯一方法是找到并终止 sqlservr 进程,让它在完成文件操作后重新启动。这看起来既沉重又危险。谁能推荐一个更礼貌的选择?

由于 SQL 连接池,您遇到了问题。这是默认完成的以优化性能。即使您对该 SqlConnection 对象调用 Dispose 和 Close,SQlConnection 也会保留。 要禁用池化,您必须在连接字符串

中将池化添加为 false
using (SportsTimerEntities ctx = new SportsTimerEntities(
 @"metadata=res://*/DataModel.csdl|res://*/DataModel.ssdl|res://*/DataModel.msl;
  provider=System.Data.SqlClient;
  provider connection string=""Data Source=(LocalDB)\v11.0;
  AttachDbFilename=C:\Work\SportsTimer\Events\559eae6a-9974-4463-8546-00824b4aad23.mdf;
  Integrated Security=True;
  Pooling=false;
  MultipleActiveResultSets=True;
  Connect Timeout=30;
  Application Name=EntityFramework"""))
{
   dbDevices = ctx.Devices.ToList();
}

如前所述,这样做是因为您有连接池 on/enabled 这通常是一件好事,因为创建连接的成本很高。你有两个选择。

  1. 关闭连接字符串中的连接池,连接将不会添加到池中。 请注意,如果在该段代码或应用程序之外建立连接,其他连接可能仍然存在
  2. 执行 SqlConnection.ClearPool 清除连接池并解锁您的本地数据库文件。

有关 sql 服务器连接池的详细信息,请参阅这篇文章 SQL Server Connection Pooling (ADO.NET)