I have a Business Layer that passes a Conn string and a SQLCommand to a Data Layer like so
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);
}
The DataLayer then just executes the sql like so
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;
}
Is it OK for me to pass the SQLCommand as a parameter like this or is there a better more accepted way of doing it.
One of my concerns is if an error occurs when executing the query the cmd.dispose line will never execute. Does that mean it will continue to use up memory that will never be released?
Update:
Following Eric’s advice I more explicitly divided the Business and Data Layers so the method in the Business Layer looks like this
public void PopulateLocalData()
{
DataLayer Data = new DataLayer(this.ConnString);
Data.UpdateLocalData();
}
and method that is called in the DataLayer looks like this.
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();
}
}
This way it is very clear that both the SQLCommand and the SQLConnection will be disposed of properly. Thanks.
Ideally, your business layer should not be aware of the implementation details of your data layer. So, whether you implement the data layer with
SqlCommandobjects or with something like NHibernate, should be irrelevant to the business layer. This makes it theoretically speaking easy to ‘shift out’ your data layer and replace it with another one.Summarizing: passing the
SqlCommandfrom the business layer to the data layer is in my eyes not considered good practice.Regarding
Dispose(): if you are using a using-statement (likeusing(SqlConnection ...)), theDispose()method is called automatically at the end of the using statement. You don’t have to do this manually.