在ORMLite查询中使用任意数量的参数
本文关键字:任意数 参数 ORMLite 查询 | 更新日期: 2023-09-27 18:30:01
我正在修复一些易受sql注入攻击的坏sql查询。大多数都是没有输入的直接查询,但我们的搜索字段采用未参数化的搜索项。下面是一个片段:
using (var db = ORMLite.Open())
{
StringBuilder sb = new StringBuilder();
sb.Append("select * from column1, column2");
if (terms.Count() > 0)
{
sb.Append("where (column1 like '%@term0%' or " + column2 + " like '%@term0%') ");
if (terms.Count() > 1)
{
for (int i = 1; i < terms.Count(); i++)
{
sb.Append("and (column1 like '%@term" + i + "%' or " + column2 + " like '%@term" + i + "%') ");
}
}
}
List<POCO> testQuery = db.Select<POCO>(sb.ToString());
}
@term组件是我打算使用参数的地方(它们过去的形式是'" + term[i] + '"
,但任何带有恶意代码的术语都会被插入。当我转到select语句时,我想添加参数。通常是这样做的:
List testQuery=db。选择(sb.ToString(),new{term0="t",term1="te",term2="ter"});
然而,我可以有任意数量的项(term.count()是项的数量)。如何传入具有任意数量术语的匿名对象?或者有更好的方法吗?
我在Postgresql中寻找几乎相同的东西。基于这个SO问题答案看起来像是"您必须执行多个查询。"
给定部分参数化,我可以从表中获得唯一的行ID查询,然后直接将这些唯一的ID粘贴回查询中——因为行ID将是安全的。
以下是我的意思的一个例子,但c#可能是错误的(对不起):
string query = "SELECT unique_id FROM table WHERE (column1 LIKE '%@term%' OR column2 LIKE '%@term%')";
string safeIDs;
List uniqueRowIDs = db.Select(query, new {term = term[0]});
for (int i = 1; i < terms.Count(); i++) {
// Loop to narrow down the rows by adding the additional conditions.
safeIDs = uniqueRowIDs.Aggregate( (current, next) => current + string.Format(", '{0}'", next) );
uniqueRowIDs = db.Select(
query + string.Format(" AND unique_id IN ({0})", safeIDs),
new {term = term[i]});
}
// And finally make the last query for the chosen rows:
safeIDs = uniqueRowIDs.Aggregate( (current, next) => current + string.Format(", '{0}'", next) );
List testQuery = db.Select(string.Format("SELECT * FROM table WHERE unique_id IN ({0});", safeIDs));
对于您的案例,另一种选择可能是只获取类似于使用参数化查询的term0
,然后在c#程序中进行比较针对用户输入的剩余术语的所有结果。