我遇到的问题是由我的应用程序连接到数据库,通过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进程,并在执行文件操作后重新启动它。这似乎既沉重又危险。任何人都可以提出更礼貌的选择吗?
答案 0 :(得分:3)
由于SQL连接池,您将面临问题。默认情况下,这是为了优化性能。即使您在该SqlConnection对象上调用Dispose和Close,SQlConnection也会保留。 要禁用池,必须在连接字符串
中将池添加为falseusing (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个选择。
有关sql server连接池的更多信息,请参阅此文章SQL Server Connection Pooling (ADO.NET)。