C# 使用字符串生成器和大量参数构建sql查询

C# 使用字符串生成器和大量参数构建sql查询,c#,sql,.net,sql-server,C#,Sql,.net,Sql Server,我正在使用循环构建查询 for (var i = 0; i < query.BlackWhiteListFieldMatchProxy.Count; i++) { sb.Append($@"( MatchType = {(int)query.BlackWhiteListFieldMatchProxy[i].MatchType} AND

我正在使用循环构建查询

for (var i = 0; i <  query.BlackWhiteListFieldMatchProxy.Count; i++)
        {
            sb.Append($@"(
                                MatchType = {(int)query.BlackWhiteListFieldMatchProxy[i].MatchType}
                        AND     EntityType = {(int)query.BlackWhiteListFieldMatchProxy[i].EntityType}
                        AND     MatchFieldType = {(int)query.BlackWhiteListFieldMatchProxy[i].MatchFieldType}
                        AND     (
                                    (
                                        MatchValue = '{query.BlackWhiteListFieldMatchProxy[i].MatchValue1}'
                                        OR MatchValue = {query.BlackWhiteListFieldMatchProxy[i].MatchValue2Or ?? "Null"}
                                    )
                                AND
                                    (
                                        {query.BlackWhiteListFieldMatchProxy[i].MatchValue2And ?? "Null"} is Null
                                        OR MatchValue2 is Null
                                        OR MatchValue2 = {query.BlackWhiteListFieldMatchProxy[i].MatchValue2And ?? "Null"}
                                    )
                                 )
                          )");

            if (i != query.BlackWhiteListFieldMatchProxy.Count - 1)
                sb.Append($@"
                            OR");
        }
如果为Null,则有效,否则实际值将不带“”

问题是我不能用像这样的东西

@MatchValue
因为我有一个名称相同的参数列表,它在列表中的编号不同,所以名称相同,并且无法正确映射(var I=0;Ifor (var i = 0; i < query.BlackWhiteListFieldMatchProxy.Count; i++) { var match = query.BlackWhiteListFieldMatchProxy[i]; cmd.Parameters.AddWithValue($"@matchType{i}", (int)match.MatchType); cmd.Parameters.AddWithValue($"@entityType{i}", (int)match.EntityType); cmd.Parameters.AddWithValue($"@fieldType{i}", (int)match.MatchFieldType); sb.Append($@"( MatchType = @matchType{i} AND EntityType = @entityType{i} AND MatchFieldType = @fieldType{i} ... etc { var match=query.BlackWhiteListFieldMatchProxy[i]; cmd.Parameters.AddWithValue($“@matchType{i}”,(int)match.matchType); cmd.Parameters.AddWithValue($“@entityType{i}”,(int)match.entityType); cmd.Parameters.AddWithValue($“@fieldType{i}”,(int)match.MatchFieldType); 某人追加($@)( MatchType=@MatchType{i} 和EntityType=@EntityType{i} 和MatchFieldType=@fieldType{i} 等
为每个必需元素添加额外的参数-因此将有
@matchType0
@matchType1
等-这样您就没有注入漏洞。需要注意的一点是:值
null
的参数不会被发送,因此请检查
null
并生成不同的SQL,或者确保使用不同的SQL在这种情况下,将参数值设置为
DBNull.value

首先,这是一种糟糕的SQL结构化方法。这种SQL有很多问题。首先也是最重要的是,它容易受到SQL注入攻击。但是,它还有其他性能相关的问题,只要提供不同的值,SQL查询就会发生变化

我建议您使用参数化SQL。下面是最基本的示例。 请注意,代码可能会根据您将要使用的库进行更改

// 1. declare command object with parameter @City
SqlCommand cmd = new SqlCommand(
    "select * from Customers where city = @City", conn);

// 2. define parameters used in command object
SqlParameter param  = new SqlParameter();
param.ParameterName = "@City";
param.Value         = inputCity;
如果我们回到您的案例,最终代码如下:

"... SQL ...
MatchType = @matchType AND
 ... SQL ..."
代码应该是这样的

cmd.Parameters.AddWithValue("@matchType", (int)match.MatchType);

和空值可以考虑使用< /P>

DbNull.Value

发布函数的完整代码。您正在将文本注入SQL;这是一个非常糟糕的主意……您说“问题是我不能使用像
@MatchValue
这样的东西,因为我有一个同名的参数列表,只是列表中的编号不同而已。这些名称将是相同的,并且不会正确地映射它。“-我不明白这是怎么一个问题:只需创建您需要填写查询的任何附加参数。您可以lain more是什么阻止你在这里使用常规参数的?因为我不明白…我有对象列表BlackWhiteListFieldMatchProxy。我不知道有多少。每个对象都有smth,如MatchType、EntityType等。但是每个对象的每个循环中其字段的值都不同。我如何使用@And映射参数取决于循环的当前步骤。名称相同,值不相同。所有这些都必须合并到一个查询中
DbNull.Value