C# 可以将SQLCommand作为参数传递吗?
我有一个业务层,它将Conn字符串和SQLCommand传递给数据层,如下所示C# 可以将SQLCommand作为参数传递吗?,c#,sql,C#,Sql,我有一个业务层,它将Conn字符串和SQLCommand传递给数据层,如下所示 public void PopulateLocalData() { System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(); cmd.CommandType = System.Data.CommandType.StoredProcedure; cmd.Comma
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);
}
然后数据层就这样执行sql
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;
}
我是否可以像这样将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都将被正确处理。谢谢。首先,您可以将其更改为:
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无用信息。为什么不将其更改为:
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();
}
}
}
是否需要其他参数?创建重载,重构。共享常用函数中的most代码。在任何地方创建新的System.Data.SqlClient.SqlCommand()都是错误的方法。理想情况下,业务层不应该知道数据层的实现细节。因此,无论您是使用
SqlCommand
对象实现数据层,还是使用类似NHibernate的对象实现数据层,都应该与业务层无关。从理论上讲,这使得“移出”数据层并用另一层替换数据层变得容易
总结:在我看来,将SqlCommand
从业务层传递到数据层并不是一个好的做法
关于
Dispose()。您不必手动执行此操作 创建命令的人应负责处理该命令。最简单的方法是从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
,例如,确实需要处理…)没有使用(SqlCommand…),但是…问题是,如果某个命令失败,该命令可能无法正确处理。连接很好。据我所知,使用(SqlCommand cmd=…)是完全有效的。