【问题标题】:How to parameterize concatenated string queries in Entity Framework Core如何在 Entity Framework Core 中参数化连接的字符串查询
【发布时间】:2019-03-09 05:05:59
【问题描述】:

在 Entity Framework Core 中,我可以像这样参数化 SQL 查询:

_context.Database.ExecuteSqlCommandAsync($"select * from table where id = {myid}");

其中 SQL 查询字符串是 FormattableString

我需要一次运行大约 100 行的 SQL 更新,当我使用 Linq 时,这会对数据库进行 100 次调用,而我可以使用类似于

的 SQL 语句轻松完成此操作
UPDATE entity 
SET column = CASE .....

在一次通话中。但我不确定如何对连接字符串执行此操作。

例如:

string sqlQuery = "UPDATE entity SET column = CASE " 

for(int i = 0; i < 10; i++){
    sqlQuery += "WHEN column2 = i THEN i + 1 ";
}

sqlQuery += "WHERE id IN (1,2,3,4,5,6,7,8,9,10)";

await _context.Database.ExecuteSqlCommandAsync(sqlQuery);

如何清理或参数化此查询?任何帮助将不胜感激!

【问题讨论】:

    标签: c# sql asp.net-core entity-framework-core


    【解决方案1】:

    您的第一个示例是一种糟糕 参数化查询的方式,因为它打开了 SQL 注入:C# 中的插值字符串功能不是专门为 SQL 命令设置的;它旨在有多种用途,因此不实施 SQL 清理。

    您应该始终使用SqlCommand 类及其Parameters 属性来确保正确清理您的参数:

    https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=netframework-4.7.2#System_Data_SqlClient_SqlCommand_Parameters

    更新:在 EF Core 中使用该特定构造函数时,内插字符串被隐式处理为 SQL 命令,并且 interpolands 被清理。

    但是,在这种情况下,您需要使用 @ 参数表示法构建您的字符串,然后使用 SqlCommand 替换参数以确保它们被清理,因为您不能将查询表示为单个模板文字。

    此外,如果您确实需要连接大量字符串,+= 是一种非常低效的方法,您应该使用 StringBuilder 来提高速度。

    【讨论】:

    • 谢谢。我可以向您保证,代码 _context.Database.ExecuteSqlCommandAsync($"select * from table where id = {myid}"); 是安全的,可能不是最佳实践,但它的 FormattableString 类不是普通字符串,因此由实体框架参数化。问题实际上在于连接 - 当我连接时,如我的示例所示,我不能再将它作为 FormattableString 传递给 ExecuteSQLCommandAsync 方法。您对我如何做到这一点有什么建议吗?
    • 用 StringBuilder 创建你的字符串(为了提高性能),而不是直接替换 {i} 和 {i+1} 替换为 @i_0 之类的东西。然后从字符串创建一个 SqlCommand 并运行一个循环,添加参数以替换参数化查询中的每个值。
    • 看起来你错过了 EF Core 标记。第一个示例对于 EF Core SQL 命令完全有效,因为 EF Core 专门处理内插字符串并为每个占位符绑定参数。
    • 这是一些非常偷偷摸摸的隐含行为。在早期版本的 EF 中意外使用它似乎是一个容易掉入的陷阱。
    • 谢谢,但我不确定如何连接字符串同时仍然能够对其进行参数化(因为FormattableString 类不支持连接),除非我做一些反思......在那里方法?
    猜你喜欢
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2022-10-25
    • 2020-02-20
    • 2020-12-07
    • 1970-01-01
    • 2022-01-25
    • 2021-09-20
    相关资源
    最近更新 更多