EF Core 2.1 抛出有关 SQL 注入(inject)的警告。它发生在我的代码片段中
var query = await _ctx.Set<TABLE>()
.FromSql("Select * from TABLE where Artikelnummer IN (" + string.Join(',', artNum) + ")")
.AsNoTracking()
.Select(z => new
{
z.Artikelnummer,
z.Property
}).ToArrayAsync();
其中 artNum
(代表 Artikel Numbers)是整数数组,例如 [1,22,34 等]。
我不能在FromSql中将artNum
作为参数传递,因为会有单引号,SQL会抛出异常。
我可以将 FromSql 重写为
.Where(x => artNum.Contains(x.Artikelnummer))
但我有比这个更大更复杂的查询,所以 LINQ to Entities 在这种情况下并不适用。 应该有 所以,问题是如何重写这个查询,这样就不会出现警告?
LINQ to Entities 的执行时间比 LINQ to SQL 长得多,因此它不是解决我的问题的合适方法。
我调查了串联会导致警告,所以应该有没有串联的解决方案。
最佳答案
我似乎无法在 EF Core 文档中找到此类警告。有趣的是,EF Core 2.1 查询转换器本身不会参数化生成的 SQL IN
值子句。如果您将查询的 .FromSql
行替换为
.Where(x => artNum.Contains(x.Artikelnummer)
顺便说一句,LINQ to Entities 相当于您的查询,它可以很好地转换和执行,所以我不知道您为什么要在这种特殊情况下使用 FromSql
。
但无论如何,您可以参数化 FromSql
通过在 sql 字符串中包含 {0}
、{1}
等占位符进行查询,并通过 params object[] 参数
传递值:
As with any API that accepts SQL it is important to parameterize any user input to protect against a SQL injection attack. You can include parameter place holders in the SQL query string and then supply parameter values as additional arguments. Any parameter values you supply will automatically be converted to a DbParameter
在你的情况下它可能是这样的:
var placeholders = string.Join(",", atrNum.Select((v, i) => "{" + i + "}"));
var values = atrNum.Cast<object>().ToArray();
.FromSql("Select * from TABLE where Artikelnummer IN (" + placeholders + ")", values)
关于c# - 警告 EF1000。 "IN"语句中参数的最佳写法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52256477/