我的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
我正在准备的值的类型,但我准备好的所有值都是字符串,所有我见过的例子都没有执行任何操作当他们处理字符串时额外。我错过了什么?
答案 0 :(得分:10)
而不是:
cmd.Parameters.AddWithValue("@" + key, searchParams[key]);
你需要使用这样的东西:
cmd.Parameters.Add("@" + key, SqlDbType.******).Value = searchParams[key];
您需要能够以某种方式确定您的参数必须是什么数据类型。
这可能是这样的:
SqlDbType.Int
表示整数值SqlDbType.VarChar
用于非Unicode字符串(不要忘记指定字符串的长度!)SqlDbType.UniqueIdentifier
对于Guids 使用AddWithValue
很方便 - 但是根据传入的值,它可以让ADO.NET根据数据类型进行猜测。大多数情况下,这些猜测非常好 - 但有时它们可以关闭。
我建议你总是明确说出你想要的数据类型。
答案 1 :(得分:1)
如果您阅读documentation,您将看到当您使用SQLCommand.Prepare时,您需要使用Parameters.Add并为每个参数指定数据类型。该链接中有一个很好的代码示例,它将向您展示如何执行此操作。