如何"重置" C#SqlCommand对象所以我可以在循环中重用它

时间:2015-08-17 16:45:28

标签: c# foreach ssis sqlcommand

我在foreach循环中有这个代码,它为每个文件夹调用一个sql函数

foreach (string strCurrentFolder in strLocalSubFolderList)
{          
    SqlCommand sqlComm1 = new SqlCommand("dbo.fnChkXfer", _sqlConn);
    sqlComm1.CommandType = CommandType.StoredProcedure;
    sqlComm1.Parameters.Add("@FileXferred",SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
    sqlComm1.Parameters.AddWithValue("@UNCFolderPath", strCurrentFolder);
    sqlComm1.Parameters.AddWithValue("@FileType", "Type 1");
    ...if files not transferred, then transfer them

    SqlCommand sqlComm2 = new SqlCommand("dbo.fnChkXfer", _sqlConn);
    sqlComm2.CommandType = CommandType.StoredProcedure;
    sqlComm2.Parameters.Add("@FileXferred",SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
    sqlComm2.Parameters.AddWithValue("@UNCFolderPath", strCurrentFolder);
    sqlComm2.Parameters.AddWithValue("@FileType", "Type 2");
    ...if files not transferred, then transfer them

    SqlCommand sqlComm3 = new SqlCommand("dbo.fnChkXfer", _sqlConn);
    sqlComm3.CommandType = CommandType.StoredProcedure;
    sqlComm3.Parameters.Add("@FileXferred",SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
    sqlComm3.Parameters.AddWithValue("@UNCFolderPath", strCurrentFolder);
    sqlComm3.Parameters.AddWithValue("@FileType", "Type 3");
    ...if files not transferred, then transfer the
}                

它工作正常,但是有很多重复的代码,这可能是不必要的。

是否可以在循环外部创建SqlCommand对象并且" reset"只是循环中的参数值?我怎么能重用这个对象? (请非常具体)。

或者我应该继续在循环中包含这个代码块,每次迭代使用不同的数据执行fn 3次?在每次几乎完全相同的情况下继续重新创建SqlCommand对象似乎效率低下。

2 个答案:

答案 0 :(得分:3)

我将列表更改为字典以添加文件类型。如果您要重用相同的sqlcommand对象,则需要在每次循环迭代中执行它。所以我补充说那部分。您可能想要添加一个尝试,也可以在那里捕获。

Dictionary<string,string> strLocalSubFolderDict = new Dictionary<string, string>();

strLocalSubFolderDict.Add( "Type 1", "Directory 1");
strLocalSubFolderDict.Add( "Type 2", "Directory 2");
strLocalSubFolderDict.Add( "Type 3", "Directory 3");

using (SqlCommand sqlComm = new SqlCommand("dbo.fnChkXfer", _sqlConn))
{
     sqlComm.CommandType = CommandType.StoredProcedure;
     sqlComm.Parameters.Add("@FileXferred", SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
     sqlComm.Parameters.Add("@UNCFolderPath");
     sqlComm.Parameters.Add("@FileType");

     foreach (var val in strLocalSubFolderDict)
     {
         sqlComm.Parameters["@UNCFolderPath"].Value = val.Value;
         sqlComm.Parameters["@FileType"].Value = val.Key;
         sqlComm.ExecuteNonQuery();
         //    ...if files not transferred, then transfer them
      }
}

在此代码中,对象在循环外部完成创建,并且foreach中的唯一更改是对对象参数的值进行的。

另一方面,我不太确定您使用 FileXferred 返回参数做了什么。你在某个地方使用它吗?

<强> 更新

这里是代码,其中每个目录都将所有FileType应用于目录。

        List<string> strLocalSubFolderList = new List<string>();
        List<string> typesList = new List<string>();

        typesList.Add("Type 1");
        typesList.Add("Type 2");
        typesList.Add("Type 3");

        using (SqlCommand sqlComm = new SqlCommand("dbo.fnChkXfer", _sqlConn))
        {
            sqlComm.CommandType = CommandType.StoredProcedure;
            sqlComm.Parameters.Add("@FileXferred", SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
            sqlComm.Parameters.Add("@UNCFolderPath");
            sqlComm.Parameters.Add("@FileType");

            foreach (var directval in strLocalSubFolderList)
            {
                foreach ( var typeval in typesList)
                {
                    sqlComm.Parameters["@UNCFolderPath"].Value = directval;
                    sqlComm.Parameters["@FileType"].Value = typeval;
                    sqlComm.ExecuteNonQuery();
                    //    ...if files not transferred, then transfer them
                }
            }
        }

答案 1 :(得分:1)

你绝对可以(甚至应该)在循环外创建SqlCommand,并随着循环的进展不断更改参数。为此,您需要在添加参数时存储参数,然后在循环中设置它们的值。您也应该在完成命令后关闭命令,最好是以某种自动方式。 using声明是最常见的选择。

using (var cmd = new SqlCommand("dbo.fnChkXfer", _sqlConn)) {
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@FileXferred",SqlDbType.Bit).Direction = ParameterDirection.ReturnValue;
    var p2 = cmd.Parameters.AddWithValue("@UNCFolderPath", DbType.Varchar, 32); // << Set the correct size
    var typeParam = cmd.Parameters.AddWithValue("@FileType", , DbType.Varchar, 32);
    foreach (string strCurrentFolder in strLocalSubFolderList) {
        p2.Value = strCurrentFolder;
        foreach (var typeVal in new[] {"Type 1", "Type 2", ...}) {
            typeParam.Value = typeVal;

            ... // Set values of the remaining parameters
            ... // Use your command as needed
        }
    }
}
// After this point all three commands will be closed automatically