c#是不是关闭sqlconnection和sqldatareader?

Posted

技术标签:

【中文标题】c#是不是关闭sqlconnection和sqldatareader?【英文标题】:c# closing sqlconnection and sqldatareader or not?c#是否关闭sqlconnection和sqldatareader? 【发布时间】:2011-05-22 02:42:57 【问题描述】:

我有这段代码:


SqlConnection conn;
string strconString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLCONN"].ToString();
conn = new SqlConnection(strconString);
string cmdstr = "select status from racpw where vtgid = " + vtgid;
SqlCommand cmdselect = new SqlCommand(cmdstr, conn);
conn.Open();
SqlDataReader dtr = cmdselect.ExecuteReader();
if (dtr.Read())

return;

else

...

dtr.Close();
conn.Close();

现在我的问题是。 如果返回,我的连接和 dtr 会自动关闭,还是应该使用布尔变量并在连接关闭后执行返回?

【问题讨论】:

【参考方案1】:

您必须在返回前关闭连接。 最好的方法是使用块,因为 SqlConnection 实现了 IDisposable 接口。在这种情况下,您不必记住即使抛出异常也必须关闭连接。

请看下面的例子:

using (var conn = new SqlConnection(strconString))

    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;
    using (var cmdselect = new SqlCommand(cmdstr, conn))
    
        conn.Open();
        using(var dtr = cmdselect.ExecuteReader())
        
            if (dtr.Read())
            
                return;
            
            else
            
                ...
            
        
    

【讨论】:

【参考方案2】:

最好使用usingblock。这将强制调用Dispose,即使您在方法中间返回:

string strconString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (SqlConnection conn = new SqlConnection(strconString))

    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;

    using(SqlCommand cmdselect = new SqlCommand(cmdstr, conn))
    
        conn.Open();
        using( SqlDataReader dtr = cmdselect.ExecuteReader())
        
            if (dtr.Read())
            
                return;
            
            else
            
                ...
            
        
    

这是可行的,因为using 实际上是一个try/finallyblock,即使您返回,finally 块也会执行并在您的SqlCommandSqlDataReader 上运行Dispose

【讨论】:

【参考方案3】:

以下是改进代码的方法:

var connectionString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (var conn = new SqlConnection(connectionString))

    conn.Open();
    using (var cmd = conn.CreateCommand())
    
        cmd.CommandText = 
            "select status from racpw where vtgid = @vtgid";

        cmd.Parameters.AddWithValue("@vtgid", vtgid);

        using (var reader = cmd.ExecuteReader())
        
            while (reader.Read())
            
                ...
            
        
    

这样您就不必担心关闭、处理、...

【讨论】:

【参考方案4】:

正如其他人所指出的,SqlConnection 实现了 IDisposable。 IDisposable 存在以便您可以控制何时释放资源。如果您不自己调用 Dispose,您的连接仍将自动关闭,但您无法控制何时发生这种情况(仅供参考,当垃圾收集器收集对象时会发生)

【讨论】:

但他可能使用连接池。这意味着,垃圾收集器不会关闭连接。在这种情况下,当他再次尝试创建和打开新连接时,他将面临 InvalidOperationException。

以上是关于c#是不是关闭sqlconnection和sqldatareader?的主要内容,如果未能解决你的问题,请参考以下文章

C# 关於数据库连接关闭的异常

为啥不用 DbConnection 而不是 SqlConnection 或 OracleConnection?

C# CancellationToken 如何与 SqlConnection.OpenAsync(token) 一起使用?

C# SQLConnection 到 SQL Azure 挂起

判断SqlConnection连接是否关闭

如果在 SqlDataReader 之前关闭 SqlConnection 会发生啥?