查询可以是:
SELECT * FROM ATable WHERE AColumn = @AColumn;
SELECT * FROM ATable WHERE AColumn >= @AColumn;
SELECT * FROM ATable WHERE AColumn BETWEEN @AColumn1 AND @AColumn2; //not necessary to support
如果有比正则表达式更好的选项,我可以提供建议。必须有一个方法/委托,实际上在找到匹配时为DbParameter
添加DbCommand
。这远远超出了我的正则表达式技能。
编辑: 实际上,我非常乐意将此限制为仅限于=,<,>,> =,< =这样,该列只能是一次。所以留下IN,而不是IN和BETWEEN。可以通过其他方式进行更复杂的查询(在评论中解释)。
-m
答案 0 :(得分:0)
确定。我做了非常基本的实现,但如果有人必须这样做,他可能会在最基本的情况下得到这个想法。这里的查询是用oracle格式编写的,如果是sql-server,我们改变:"占位符"到@。
public void AddParameters(string query, List<object> valueList)
{
int orderNr = 0;
string newQuery = Regex.Replace(query, @"(?<Operator>=|<=|>=|<|>)\s?(?<PlaceHolder>:)(?<ColumnName>([A-Za-z0-9\-]+))",
new MatchEvaluator(
delegate(Match match)
{
var param = this.ProviderFactory.CreateParameter();
param.ParameterName = match.Groups["ColumnName"].Value;
param.DbType = GetDbType(valueList[orderNr]);
param.Value = valueList[orderNr++];
Parameters.Add(param);
if (ProviderType == DbProviderType.SqlServer)
return string.Format("{0}@{1}", match.Groups["Operator"].Value, match.Groups["ColumnName"]);
return match.Value;
}
));
}
private DbType GetDbType(object value)
{
if (value is int)
return DbType.Int32;
else if (value is double)
return DbType.Double;
else if (value is string)
return DbType.String;
else
return DbType.DateTime;
}
像这样使用:
query = "SELECT * FROM ATable WHERE ColumnA=:ColumnA AND ColumnB=ColumnB AND (LanguageId=:LANGUAGEID OR LanguageId = '*')";
cmd.AddParameters(query, new List<object> { tableId, fieldName, languageId });
这里cmd是我自己的DbCommand-class抽象。