我正在EF Core中构建SQL搜索。 Microsoft建议您不要连接字符串,因为它会使应用程序容易受到SQL注入的影响,如Microsoft文档:https://docs.microsoft.com/en-us/ef/core/querying/raw-sql中所述。
对于原始SQL查询始终使用参数化: 验证用户输入,请始终对使用的任何值使用参数化 在原始SQL查询/命令中。接受原始SQL字符串的API,例如 FromSql和ExecuteSqlCommand允许将值轻松传递为 参数。接受的FromSql和ExecuteSqlCommand的重载 FormattableString还允许在字符串中使用字符串插值语法 防止SQL注入攻击的方法。
如果您使用字符串串联或插值来动态 构建查询字符串的任何部分,或将用户输入传递给 可以执行以下输入的语句或存储过程: 动态SQL,则您负责验证对 防止SQL注入攻击。
此数据库中存储的信息不敏感,但是显然我不想让数据库容易受到攻击。
我有一个参数List<string> searchTerms
,我需要对其进行遍历并基于此列表构建查询。
我将把字符串和SQL查询一起使用,但是我只能看到如何通过串联来做到这一点。现在我的代码看起来像这样。
var query = String.Format("SELECT ... where MySqlField like '%{0}%'", searchTerm[0]);
for (int i = 1; i < searchTerm.Count(); i++)
{
query += String.Format(" and MySqlField like '%{0}%'", searchTerm[i]);
}
var results = context.MySqlTable.FromSql(query);
即使我使用的是插值法,在这里进行额外的验证就足够了吗?我想念什么吗?
是否存在可以使用列表执行相同操作的linq查询?
答案 0 :(得分:1)
我目前无法对其进行测试,所以我让您了解这种方法
List<string> ph = new List<string>();
int count = 0;
foreach(string s in searchTerm)
{
ph.Add($"MySqlField LIKE '%{{{count}}}%'");
count++;
}
if(count > 0)
query = query + " WHERE " + string.Join(" OR ", ph);
var results = context.MySqlTable.FromSql(query, searchTerm.ToArray());
虽然它看起来像是字符串连接方法,但我们可以阅读docs
虽然看起来像String.Format语法,但是提供的值是 包装在参数中,并将生成的参数名称插入到 指定了{0}占位符。
答案 1 :(得分:1)
选项很少:
以XML(如果使用更新的SQL Server,则为JSON)传递值,然后编写静态XML / JSON查询。
创建一个临时表,将所有搜索值插入到临时表中,然后执行静态查询。
答案 2 :(得分:0)
您的代码经过一些修改后应该足够好了
var query = String.Format("SELECT ... where 1=1 ");
for (int i = 0; i < searchTerm.Count(); i++)
{
query += $" and MySqlField like '%'+{{{i}}}+'%'";
}
var results = context.MySqlTable.FromSql(query, searchTerm.ToArray());
答案 3 :(得分:-1)
如果您使用EF,我建议您调查LINQ。对于安全性和性能而言,使用原始字符串sql并不是一个好主意。 LINQ提供了一种执行查询的可靠方法。只是要小心如何编写查询,因为LINQ可能会过度尝试使查询变得过于复杂。
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
编辑:
我错过了您帖子的最后一行。抱歉,以下内容应有助于您走上正确的路:
for (var item in searchTerms) {
query = query.Where(w => w.MySqlField.Contains(item.Value));
}