当我创建临时表时,我收到一条错误消息,告诉我临时表已经存在。临时表对于会话是唯一的,所以看起来我的连接没有正确关闭,我认为它可能与我在using语句中的return语句有关。
我有以下代码:
using (IDbConnection connection = dbConnectionHandler.CreateConnection())
{
connection.Open();
CreateATempTable();
PopulateTempTable();
DataSet ds = CallStoredProcThatUsesTempTable();
return ds;
}
我在几个地方使用这种代码来创建一个具有相同名称的临时表。
不幸的是,我收到以下错误:There is already an object named '#MyTempTable' in the database
。
现在,我知道临时表对于会话是唯一的,因此一旦会话关闭,它就会消失。
我认为有三件事可能导致这种情况......
有谁知道它是哪一个?或者如果它是我没想过的东西?
答案 0 :(得分:6)
我猜这里但是检查你的数据库连接池设置。尝试关闭池,看看它是否有帮助。
通常,在.NET库级别关闭/部署连接时,不会关闭真正的数据库服务器连接。它只是返回到数据提供程序内部的连接池,并在程序请求具有相同参数和凭据的另一个连接时重用。我不认为数据库会话在返回池之前以任何方式重置,除了打开的事务和可能的一些基本参数。更加昂贵的物品,如临时桌子,都是孤立的。
你可以关闭池(非常低效)。或者,您可以在尝试创建临时表之前检查临时表的存在,并删除其内容(如果存在)。或者您可以在关闭连接之前删除临时表。
答案 1 :(得分:3)
我很确定将调用connection.Dispose()(以及connection.Close())。
您可以通过执行1)和2)轻松验证,并检查问题是否仍然存在。解决方案可能是3),解释将是连接池。
答案 2 :(得分:1)
除非发生电源循环或其他严重奇怪的角落情况处理,否则将被召唤。
如果你想要证明包装对象并在其中放置一个断点。
答案 3 :(得分:1)
使用块被转换为引擎盖下的try / catch / finally块。是的,无论使用区块内的返回如何,它都将被处置。
答案 4 :(得分:1)
不,始终会调用connection.Close,因为内部使用将其置于try / finally块中。
您还可以考虑连接池。尝试将您的代码包装在TransactionScope中。
答案 5 :(得分:0)
在不了解正在使用的数据库连接库的情况下,我猜它不是前两个; using
专门用于在退回方法时更容易清理这些资源;它直接类似于Java中的普通try...finally
块或类似的块。
换句话说,return
将离开块,并且将在连接上调用Dispose
方法,假设执行此类方法,应调用Close
方法作为该过程的一部分。
这里的关键点是“理智的实施”。
答案 6 :(得分:0)
回答你的问题:
答案 7 :(得分:0)
using语句将处理该对象,如果它的类是IDisposable,即使在using块中有一个return语句。
连接池保留了您的#temptable,您可能希望手动删除该表。
答案 8 :(得分:0)
这是由连接池引起的。在事务中包装您正在执行的操作,并在最后将其回滚。或者,在填充ds之后删除临时表。