Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可以将SQLCommand作为参数传递吗?_C#_Sql - Fatal编程技术网

C# 可以将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

我有一个业务层,它将Conn字符串和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);
    }
然后数据层就这样执行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=…)是完全有效的。