2010-12-08 80 views
4

我有這樣一段代碼:c#關閉sqlconnection和sqldatareader與否?

 
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都會自動關閉,或者我應該使用布爾變量和我的連接都處在關閉後進行回報?

回答

9

您必須關閉返回之前的連接。 最好的方式做到這一點是使用塊,因爲的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 
      { 
       ... 
      } 
     } 
    } 
} 
3

最好的辦法是使用using塊來代替。這將強制調用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/finally塊,即使你回來,最終被執行的塊並運行DisposeSqlCommandSqlDataReader

4

下面是如何提高你的代碼:

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()) 
      { 
       ... 
      } 
     } 
    } 
} 

這樣你就不需要擔心收,處置,...

1

正如其他人指出,SqlConnection的實現IDisposable。存在IDisposable,以便您可以控制何時釋放資源。如果你不調用Dispose你自己,你的連接仍然會自動關閉,但你有過當這可能發生(FYI其會在垃圾收集器收集的對象發生)

+0

但他可能使用連接池無法控制。這意味着,垃圾收集器不會關閉連接。在那種情況下,當他嘗試再次創建並打開新連接時,他將面臨InvalidOperationException。 – Egor4eg 2010-12-08 09:47:14

相關問題