EntityFramework保持连接打开?

时间:2016-02-25 14:53:52

标签: c# entity-framework localdb

我遇到的问题是由我的应用程序连接到数据库,通过EF,在我不期望它们打开的时候打开。我正在为运动事件和动态创建新数据库做一个计时系统,复制现有的DB文件并使用根据需要使用正确文件名构建的连接字符串附加它们。

创建新文件的一种方法是将其基于现有事件,即复制然后清除一堆数据。如果我在加载现有事件时尝试此操作,我无法复制该文件,因为SQL Server已将其锁定,并且我无法显式分离它,因为SQL Server声称它正在使用中。当我查看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进程,并在执行文件操作后重新启动它。这似乎既沉重又危险。任何人都可以提出更礼貌的选择吗?

2 个答案:

答案 0 :(得分:3)

由于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();
}

答案 1 :(得分:2)

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

  1. 关闭连接字符串中的连接池,连接不会添加到池中。 请注意,如果在该段代码或应用程序之外进行连接,则其他连接仍然存在。
  2. 执行SqlConnection.ClearPool清除连接池并解锁本地数据库文件。
  3. 有关sql server连接池的更多信息,请参阅此文章SQL Server Connection Pooling (ADO.NET)