2011-10-21 108 views
7

但是,在運行代碼分析器之後,我發現OracleParameter還實現了IDisposable,現在我已經在USING語句中包裝了OracleConnection和OracleCommand對象。以下代碼是否正確?有更好的可讀性或結構技術嗎?乍一看,它似乎與USING陳述混雜在一起:C#IDisposable使用方法:最佳實踐

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
     } 

     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 
     } 

     using (OracleDataReader dr = cmd.ExecuteReader()) 
     { 
      // loop data here... 
     } 
    } 
} 

回答

7

希望只在其使用的最末端處置的參數,包括查詢過程中(和結果的可能閱讀):

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 

      using (OracleDataReader dr = cmd.ExecuteReader()) 
      { 
       // loop data here... 
      } 
     } 
    } 
} 

注意,你可以把多個using聲明一排。這是因爲,像if聲明,

  1. 一個using聲明被認爲是一個簡單的語句(即使有塊);和
  2. A using語句可以採用下面的塊或語句。
+0

雖然有很多相似的答案,但我很欣賞你提供了例子和評論。 – Shawn

+0

謝謝!很高興我能幫上忙。 :-) –

1

我不確定這是否能正常工作。考慮到在使用結束時,兩個參數應該已經被處置。您的cmd.Parameters對象仍然保留對它們的引用的事實並不排除可能在OracleParameter Dispose方法中發生的情況。對於所有密集目的,該特定對象的開發人員可能會清除OracleCommand預計將填充的字段。

那裏有一些危險。如果您完全確定要正確處理您的OracleParameters,我建議您在OracleDataReader之後處理它們。

請記住,當您完成使用該對象時,通常會撥打Dispose。你告訴它釋放所有資源回到游泳池。如果您沒有使用對象,請不要過早處理它。

0

不,這是不正確的,因爲即使在使用它們之前,您仍在處理參數。

相反,你應該這麼像這樣

OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input); 

param1.Value = int.Parse(value1); 
cmd.Parameters.Add(param1); 


OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input); 

param2.Value = value2; 
cmd.Parameters.Add(param2); 


using (OracleDataReader dr = cmd.ExecuteReader()) 
{ 
    // loop data here... 
} 

param1.dispose(); 
param2.dispose(); 
1
using (OracleConnection conn = new OracleConnection(connectionstring)) 
using (OracleCommand cmd = new OracleCommand(sql, conn)) 
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, 
     System.Data.ParameterDirection.Input)) 
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, 
     System.Data.ParameterDirection.Input)) 
} 
    conn.Open(); 
    cmd.BindByName = true; 

    param1.Value = int.Parse(value1); 
    cmd.Parameters.Add(param1); 

    param2.Value = value2; 
    cmd.Parameters.Add(param2); 

    using (OracleDataReader dr = cmd.ExecuteReader()) 
    { 
     // loop data here... 
    } 
} 
0

你可以看看連接和命令的源代碼,它配置的參數?如果連接或命令對象處理模式包裝參數並將它們丟棄後丟棄。你應該擔心它。我認爲它會/應該。

0

此錯誤代碼不正確。您創建的參數仍在using語句範圍之外使用,因爲您將它們添加到參數集合中,但using語句將在控制權離開範圍時調用Dispose。這意味着,到時會使用命令theya裏面的參數將被disoised已經

0

MSDN,你只需要使用usingConnectionDataReader對象。我從來沒有見過使用ADO.NET參數對象的using(或.Dispose())。如果這是必要的或者甚至是可取的,我認爲在過去的10年內已經有一段時間了。

+2

MSDN正在討論由BCL提供的對象。 Oracle的這些實現可能需要處理參數。如果他們不打算被處置,他們爲什麼要實施IDisposable? –

+0

或者他們很可能不會。我從來沒有見過任何ADO.NET代碼(對於Oracle的實現或任何其他人),它們在參數對象上調用Dispose()或將它放在'using'塊中。再次說明,如果處理參數是必要的,那麼很久以前就會出現這種情況。 – MusiGenesis

+2

所以你的建議是,即使一個對象實現了IDisposble,除非知道它是一個問題,否則不要處理它?聽起來像對我不好的建議。 –