C# 如何在一条语句中向SQL命令添加多个参数?

C# 如何在一条语句中向SQL命令添加多个参数?,c#,sql,C#,Sql,我有如下六行参数: cmd.Parameters.AddWithValue("@variable1", myvalue1); cmd.Parameters.AddWithValue("@variable2", myvalue2); cmd.Parameters.AddWithValue("@variable3", myvalue3); string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3

我有如下六行参数:

    cmd.Parameters.AddWithValue("@variable1", myvalue1);
    cmd.Parameters.AddWithValue("@variable2", myvalue2);
    cmd.Parameters.AddWithValue("@variable3", myvalue3);
string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" };
for (int i = 0; i < 6; i++) { cmd.Parameters.AddWithValue("@variable" + (i + 1),myValues[i]); }
等等

有没有办法在不直接插入cmd.CommandText的情况下将其压缩一点


编辑:我想我可以用一个好的老式阵列。不过我还是决定坚持这一点。

据我所知,您的代码在行数方面是最紧凑的,但是您可以使用
列表
和对象初始值设定项语法,只让一行以分号结尾来构建参数列表,然后将该列表作为AddRange方法所需的参数数组传递

 List<SqlParameter> prm = new List<SqlParameter>()
 {
     new SqlParameter("@variable1", SqlDbType.Int) {Value = myValue1},
     new SqlParameter("@variable2", SqlDbType.NVarChar) {Value = myValue2},
     new SqlParameter("@variable3", SqlDbType.DateTime) {Value = myValue3},
 };
 cmd.Parameters.AddRange(prm.ToArray());
List prm=新列表()
{
新的SqlParameter(“@variable1”,SqlDbType.Int){Value=myValue1},
新的SqlParameter(“@variable2”,SqlDbType.NVarChar){Value=myValue2},
新的SqlParameter(“@variable3”,SqlDbType.DateTime){Value=myValue3},
};
cmd.Parameters.AddRange(prm.ToArray());
注意,使用这种方法,您需要正确定义参数的数据类型。在我的示例中,我使用了一些任意类型来显示正确的语法

有点离题了,我认为在这种一般情况下,有兴趣指出,当您想要获得尽可能最好的性能时,
AddWithValue
是不被考虑的

在这篇关于MSDN的文章中,我们很好地解释了为什么出于性能原因应该避免使用
AddWithValue
方法。
简而言之,使用
AddWithValue
对于
Sql Server Optimizer
可能是一个问题,因为字符串类型的参数是以等于字符串当前长度的大小传递的。但这将迫使
Sql Server优化器
放弃为上一次相同调用创建的查询计划,但该调用的字符串长度不同。

最好调用SqlParameter构造函数,指定参数的类型和大小,不要担心如何压缩调用的大小。

为了参数起见,使用您给出的代码示例,其中存储的过程变量字面上被命名为variabe1、variable2等。。。你可以这样做:

    cmd.Parameters.AddWithValue("@variable1", myvalue1);
    cmd.Parameters.AddWithValue("@variable2", myvalue2);
    cmd.Parameters.AddWithValue("@variable3", myvalue3);
string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" };
for (int i = 0; i < 6; i++) { cmd.Parameters.AddWithValue("@variable" + (i + 1),myValues[i]); }
string[]myValues=新字符串[]{“myvalue1”、“myvalue2”、“myvalue3”、“myvalue4”、“myvalue5”、“myvalue6”};
对于(inti=0;i<6;i++){cmd.Parameters.AddWithValue(“@variable”+(i+1),myValues[i]);}
2行丑陋的代码。。。哈哈

如果你说25-50个值,像这样的循环可能会派上用场,尽管我不经常看到这样的情况。您可以使用两个数组,一个用于变量名,一个用于值,只要索引匹配,那么这将起作用:

string[] myVarNames = new string[] { "variable1", "variable2", "variableThree", "variable4our", "variableFIVE", "variableSIX" };
string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" };

for (int i = 0; i < 6; i++)
{
    cmd.Parameters.AddWithValue("@" + myVarNames[i], myValues[i]);
}
string[]myVarNames=新字符串[]{“variable1”、“variable2”、“variabletree”、“variable4our”、“variable5”、“variable6”};
字符串[]myValues=新字符串[]{“myvalue1”、“myvalue2”、“myvalue3”、“myvalue4”、“myvalue5”、“myvalue6”};
对于(int i=0;i<6;i++)
{
cmd.Parameters.AddWithValue(“@”+myVarNames[i],myValues[i]);
}

我逐字回答了这个问题:“…在一句话中”:)

Steve代码很好,但可以使用最规范的构造函数和隐式数组声明将其简化一点:

cmd.Parameters.AddRange(new []
    {
        new SqlParameter("@variable1", myValue1),
        new SqlParameter("@variable2", myValue2),
        new SqlParameter("@variable3", myValue3),
    });

我认为这将很好地理解为这样一行:

    cmd.Parameters.AddWithValue("@variable1", myvalue1);
    cmd.Parameters.AddWithValue("@variable2", myvalue2);
    cmd.Parameters.AddWithValue("@variable3", myvalue3);
string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" };
for (int i = 0; i < 6; i++) { cmd.Parameters.AddWithValue("@variable" + (i + 1),myValues[i]); }
用法:

// One liner to create and set SqlCommand parameters
cmd.SetParameters(Parameter("@variable1", myvalue1), Parameter("@variable2", myvalue2), Parameter("@variable3", myvalue3));
要支持一行程序,您需要创建一个函数,将Sql参数包装为语义包(类似元组),如下所示:

public SqlParameter Parameter(string name, object value)
{
    return new SqlParameter(name, value);
}
创建一个带有扩展方法的静态类,为我们提供所需的语法支持。请注意,使用了params关键字,它允许在上述SetParameters调用中使用多个参数

public static class SqlDataUtils
{
    public static void SetParameters(this SqlCommand command, params SqlParameter[] parameters)
    {
        command.Parameters.AddRange(parameters);
    }
}

这个答案是受

的公认答案启发而来的,恐怕我看不出它是如何比原始代码更压缩的。没有压缩它只是一行而不是三行(当然不包括最后的AddRange)哦,实际上有更多行,但是如果你数分号。。。只是开玩笑。从生成的IL代码来看,origina操作代码是最简洁的。@Steve如果myValue1是一个数组,我将如何使用您相同的符号实现它?我不知道您为什么要压缩它,但我非常确定您所采用的方式是最直接和简洁的方式。没有办法缩短它。你为什么要这么做?你可以使用一个完全不同的图书馆或自动化的东西,但它不会更便宜,只是看起来不同而已。结果发现没有捷径了!据我所知,没有办法缩短这个时间。六行并不坏,但是如果你的参数真的开始变大,如果你觉得有必要的话,你可以考虑一些循环算法。否则,我会坚持使用复制粘贴作为朋友。这可能会为OleDB和ODBC带来一个有趣的解决方案,它们有未命名的有序参数。是的,我在粘贴中广泛使用了第二个选项,而不是两个数组,使用
字典
将消除索引不匹配的担忧。@Shoosha我去用字典重写,但意识到它不满足“压缩”代码的OP要求。。。我认为使用字典实际上会给OP问题增加更多的代码行。这一定是我在3年前给出数组解决方案而不是字典的原因。OP决定使用他的原始代码,在我看来,这可能是更好的解决方案。谢谢除非其中一个值是值为零的整数。看来你是对的。将硬编码的0转换为object
新的SqlParameter(“@param”,(object)0)
会起作用,但我同意这不好。不,我不是。感谢您的链接,这和令人沮丧一样有趣:“始终指定正确的数据类型、长度、精度和比例将确保您在执行时没有执行数据类型强制。”-唉,我太失望了