5

我的 WCF Web 服务中有以下代码片段,它根据所提供字典的值的格式构建一组 where 条件。

public static Dictionary<string, string>[] VehicleSearch(Dictionary<string, string> searchParams, int maxResults)
{
    string condition = "";
    foreach (string key in searchParams.Keys)
    {
        //Split out the conditional in case multiple options have been set (i.e. SUB;OLDS;TOY)
        string[] parameters = searchParams[key].Split(';');
        if (parameters.Length == 1)
        {
            //If a single condition (no choice list) check for wildcards and use a LIKE if necessary
            string predicate = parameters[0].Contains('%') ? " AND {0} LIKE @{0}" : " AND {0} = @{0}";
            condition += String.Format(predicate, key);
        }
        else
        {
            //If a choice list, split out query into an IN condition
            condition += string.Format(" AND {0} IN({1})", key, string.Join(", ", parameters));
        }
    }

    SqlCommand cmd = new SqlCommand(String.Format(VEHICLE_QUERY, maxResults, condition));
    foreach (string key in searchParams.Keys)
        cmd.Parameters.AddWithValue("@" + key, searchParams[key]);
    cmd.Prepare();

请注意,字典中的值被显式设置为字符串,并且它们是唯一被发送到AddWithValue语句中的项目。这会产生如下 SQL:

SELECT TOP 200 MVINumber AS MVINumber
    , LicensePlateNumber
    , VIN
    , VehicleYear
    , MakeG
    , ModelG
    , Color
    , Color2
FROM [Vehicle_Description_v]
WHERE 1=1 AND VIN LIKE @VIN

并且错误地说

System.InvalidOperationException:SqlCommand.Prepare 方法要求所有参数都具有明确设置的类型。

我所做的所有搜索都表明我需要告诉AddWithValue我正在准备的值的类型,但是我所有准备的值都是字符串,而且我看到的所有示例在处理字符串时都没有执行任何额外的操作. 我错过了什么?

4

2 回答 2

14

而不是这个:

cmd.Parameters.AddWithValue("@" + key, searchParams[key]);

你需要使用这样的东西:

cmd.Parameters.Add("@" + key, SqlDbType.******).Value = searchParams[key];

您需要能够以某种方式确定您的参数必须是什么数据类型。

这可能是这样的:

  • SqlDbType.Int对于整数值
  • SqlDbType.VarChar对于非 Unicode 字符串(不要忘记指定字符串的长度!)
  • SqlDbType.UniqueIdentifier用于指南
    等。

使用AddWithValue很方便 - 但它让 ADO.NET 根据传入的值猜测数据类型。大多数情况下,这些猜测非常好 - 但有时它们可​​能会被关闭。

我建议您始终明确说出您想要的数据类型。

于 2012-08-13T17:10:07.303 回答
1

如果您阅读文档,您会发现在使用 SQLCommand.Prepare 时,您需要使用 Parameters.Add 并为每个参数分配一个数据类型。该链接中有一个很好的代码示例,它将向您展示如何执行此操作。

于 2012-08-13T17:32:23.873 回答