2010-04-23 52 views
8

我有一個傳遞一個康涅狄格州串和一個SqlCommand到數據層,像這樣可以通過SQLCommand作爲參數嗎?

public void PopulateLocalData() 
    { 
     System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(); 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
     DataLayer.DataProvider.ExecSQL(ConnString, cmd); 
    } 

數據層則只是執行像這樣

 public static int ExecSQL(string sqlConnString, System.Data.SqlClient.SqlCommand cmd) 
    { 
     int rowsAffected; 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      rowsAffected = cmd.ExecuteNonQuery(); 
      cmd.Dispose(); 
     } 
     return rowsAffected; 
    } 

的SQL是它確定爲我業務層像這樣傳遞SQLCommand作爲參數,還是有更好的方法來實現它。 我所關注的一個是,如果執行查詢cmd.dispose行不執行時發生錯誤。這是否意味着它將繼續使用永遠不會被釋放的內存?

更新:

繼Eric的意見,我更明確地劃分了業務和數據層,以便在業務層的方法看起來像這樣

public void PopulateLocalData() 
    { 
     DataLayer Data = new DataLayer(this.ConnString); 
     Data.UpdateLocalData(); 
    } 

和方法,被稱爲在數據層看起來是這樣的。

 public void UpdateLocalData() 
    { 
     using (SqlConnection conn = new SqlConnection(this.ConnString)) 
     using(SqlCommand cmd = new SqlCommand()) 
     { 
      cmd.CommandType = System.Data.CommandType.StoredProcedure; 
      cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
      conn.Open(); 
      cmd.Connection = conn; 
      cmd.ExecuteNonQuery(); 
     } 
    } 

這種方式很清楚SQLCommand和SQLConnection都會被正確處置。謝謝。

回答

6

理想的情況下,業務層不應該知道你的數據層的實現細節。所以,不管你用SqlCommand物品或類似NHibernate的實現數據層,應該是無關的業務層。這使得理論上來說很容易將數據層「移出」並用另一個替換掉。

總結:從業務層到數據層傳遞SqlCommand在我眼裏沒有考慮好的做法。

關於Dispose():如果您正在使用using語句(如using(SqlConnection ...)),則會在using語句結束時自動調用Dispose()方法。您不必手動執行此操作。

+0

。沒有使用(SqlCommand ...),但是...問題是如果某些事情失敗,命令可能無法正確處置。連接很好。 – cHao 2010-04-23 14:02:00

+0

據我所知,使用(SqlCommand cmd = ...)是完全有效的。 – 2010-04-23 14:08:42

-1

那麼對於初學者,你可以將其更改爲:

public static int ExecSQL(string sqlConnString, System.Data.SqlClient.SqlCommand cmd) 
{ 
    int rowsAffected; 
    try 
    { 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      rowsAffected = cmd.ExecuteNonQuery(); 
     } 
    } finally { 
     cmd.Dispose(); 
    } 
    return rowsAffected; 
} 

此外,我一般分開我的業務和數據層比你做的更多。我的業務層會在數據層調用一個方法「GetLocalSurvey」,它將處理所有的SQL廢話。

0

你爲什麼不改成這樣:

public static int ExecProcedure(string sqlConnString, string procedureName) 
{ 
    using (var cmd = new System.Data.SqlClient.SqlCommand()) 
    { 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = procedureName; 
     int rowsAffected; 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      return cmd.ExecuteNonQuery(); 
     } 
    } 
} 

你想額外的參數?創建重載,重構。共享功能最多的代碼。到處創建new System.Data.SqlClient.SqlCommand()是錯誤的方法。

0

的一個創建命令應該負責處置它。造成這種情況的最簡單的方法是從ExecSql刪除調用cmd.Dispose,而是調用你的函數是這樣的:

public void PopulateLocalData() 
{ 
    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand()) 
    { 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
     DataLayer.DataProvider.ExecSQL(ConnString, cmd); 
    } 
} 
我所關注的

之一是,如果執行查詢cmd.dispose線將在發生錯誤時從不執行。這是否意味着它將繼續使用永遠不會被釋放的內存?

巧合的是,SqlClient.SqlCommand不需要處置。然而,這是一個實現細節,你不應該依賴 - 的一般規則仍然是:如果它實現IDisposable,處理它(SqlCeClient.SqlCeCommand,例如,確實需要處理......)

相關問題