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.VarCharUnicode以外の文字列の場合(文字列の長さを指定することを忘れないでください!)
  • SqlDbType.UniqueIdentifierGUID
    など

使用AddWithValueは便利ですが、渡された値に基づいてデータ型を推測するのはADO.NETに任されています。ほとんどの場合、これらの推測はかなり適切ですが、場合によってはオフになることもあります。

必要なデータ型を常に明示的に指定することをお勧めします。

于 2012-08-13T17:10:07.303 に答える
1

ドキュメントを読むと、SQLCommand.Prepare を使用している場合は、Parameters.Add を使用して各パラメーターにデータ型を割り当てる必要があることがわかります。そのリンクには、その方法を示す優れたコードサンプルがあります。

于 2012-08-13T17:32:23.873 に答える