c# - 警告 EF1000。 "IN"语句中参数的最佳写法是什么?

标签 c# sql linq asp.net-core-2.1 ef-core-2.1

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/

相关文章:

sql - MySql批量加载命令行工具

c# - Linq 查询具有 where 条件的表中的不同数据

c# - 何时在 LINQtoObjects 上使用带有 lambda 的扩展方法来过滤集合?

C# Array.Contains() 编译错误

c# - Unity 3D 中的 MonoBehaviour 是什么?

c# - 按字符拆分字符串

c# - 保护软件免遭盗版

sql - 使用 uniqueidentifier 作为主键并使用参数化查询从客户端应用程序插入它

c# - 我该如何解决这个问题?单元类型存在于两个dll文件中

c# - 更新 mdb 数据库表