return语句是否可以阻止using语句关闭与数据库的连接?

时间:2009-02-25 23:27:51

标签: c# using-statement dbconnection temp-tables

当我创建临时表时,我收到一条错误消息,告诉我临时表已经存在。临时表对于会话是唯一的,所以看起来我的连接没有正确关闭,我认为它可能与我在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

现在,我知道临时表对于会话是唯一的,因此一旦会话关闭,它就会消失。

我认为有三件事可能导致这种情况......

  1. 我需要调用connection.Close()
  2. 我需要将return语句放在我的using语句
  3. 之外
  4. 我需要删除我在返回之前创建的临时表
  5. 有谁知道它是哪一个?或者如果它是我没想过的东西?

9 个答案:

答案 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)

回答你的问题:

  1. 当调用连接的Dispose方法时,using语句将隐式关闭连接。
  2. 不需要:http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. 试试吧。

答案 7 :(得分:0)

using语句将处理该对象,如果它的类是IDisposable,即使在using块中有一个return语句。

连接池保留了您的#temptable,您可能希望手动删除该表。

答案 8 :(得分:0)

这是由连接池引起的。在事务中包装您正在执行的操作,并在最后将其回滚。或者,在填充ds之后删除临时表。