.Net:在这个例子中,我的连接是通过Dispose关闭的吗?

时间:2011-12-23 20:06:33

标签: c# ado.net

以下是我的示例的简化版本:

using (DbCommand cmd = new SqlCommand("myProcedure", (SqlConnection)DataAccessHelper.CreateDatabase().CreateConnection()) { CommandType = CommandType.StoredProcedure })
{
    cmd.Connection.Open();
    using(IDataReader dr = cmd.ExecuteReader())
        doWork(dr);
}

当处理命令时,连接是否已关闭?或者我是否需要首先使用语句进行连接,然后在闭包中创建命令?

3 个答案:

答案 0 :(得分:11)

如果您希望阅读器关闭连接,可以使用ExecuteReader()的重载:

...
using (IDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
...

默认情况下,配置阅读器不会释放连接。 - see MSDN for more info...

要解决Close() vs Dispose()的问题,MSDN声明:

  

如果DbConnection超出范围,则不会关闭。因此,   您必须通过调用Close或Dispose显式关闭连接,   这在功能上是等同的。

因此,不需要必须设置自闭合连接。主要区别在于可以重新打开关闭的连接,但是不能打开连接。 Dispose()执行的主要附加工作是将内部设置为null,因为连接超出范围,所以不会产生太大影响。

答案 1 :(得分:4)

James Michael Hare的作品,但你也想要处理你的连接。试试这个:

using (SqlConnection conn = (SqlConnection)DataAccessHelper.CreateDatabase().CreateConnection())
using (DbCommand cmd = new SqlCommand("myProcedure", conn) { CommandType = CommandType.StoredProcedure })
{
    cmd.Connection.Open();
    using(IDataReader dr = cmd.ExecuteReader())
        doWork(dr);
}

答案 2 :(得分:3)

你应该使用

using(var connection = (SqlConnection)DataAccessHelper.CreateDatabase().CreateConnection())
{
 connection.Open(); 
 ....
}

因为即使你关闭了连接,你仍然需要处理它。请注意,SQLConnection会在Close中调用Dispose。问题是,如果你必须自己调用Close,你必须将它放入try...catch,这样才能保证你不会有内存泄漏。框架中还有其他类型不会在Close中调用Dispose,我认为应该将其包裹起来。