Cai*_*ard 18 c# entity-framework-core ef-core-3.1
升级到 EFCore 3.1 后出现不推荐使用的警告:
警告 CS0618 'RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync(DatabaseFacade, RawSqlString, params object[])' 已过时:'对于使用纯字符串的 SQL 查询的异步执行,请改用 ExecuteSqlRawAsync。对于使用内插字符串语法创建参数的 SQL 查询的异步执行,请改用 ExecuteSqlInterpolatedAsync。
警告 CS0618 'RelationalDatabaseFacadeExtensions.ExecuteSqlCommand(DatabaseFacade, RawSqlString, params object[])' 已过时:'对于使用纯字符串执行 SQL 查询,请改用 ExecuteSqlRaw。要使用内插字符串语法执行 SQL 查询以创建参数,请改用 ExecuteSqlInterpolated。
它们相关的旧代码如下所示:
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);
await context.Database.ExecuteSqlCommandAsync("DELETE FROM Table2 WHERE ID = @p0", id);
Run Code Online (Sandbox Code Playgroud)
查阅精美手册,@somename根本没有讨论典型的 SQL Server 参数,实际上我什至看不到文档中的示例代码(它们显示在表名后打开括号)是有效的 SQL 语法:
context.Database.ExecuteSqlRaw("SELECT * FROM [dbo].[SearchBlogs]({0})", userSuppliedSearchTerm)
Run Code Online (Sandbox Code Playgroud)
我没有看到文档在哪里定义了userSuppliedSearchTerm变量的内容或其类型,我正在努力了解它如何成为一个明智的 SQL 块(string userSuppliedSearchTerm = "WHERE id = 123";带有烘焙值?SQL 注入?)或单个原始值( int userSuppliedSearchTerm = 123) 那么这是否意味着它是某种自定义类型,指定了 db 列名称和值?EFCore 如何知道要查询表中的哪一列?EFCore 是否整理了括号中呈现的语法错误?EFCore 必须使用括号才能理解查询吗?
最终我的问题是:鉴于我的ExecuteSqlCommand代码有意义,并且文档ExecuteSqlRaw没有意义/似乎解释得很差,我们如何从这个工作代码出发:
var id = 123;
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);
Run Code Online (Sandbox Code Playgroud)
使用 ExecuteSqlRaw?
SomeType x = ???;
context.Database.ExecuteSqlRaw("???", x);
Run Code Online (Sandbox Code Playgroud)
Iva*_*oev 32
规则很简单。
EF Core 2.x 有 3 个ExecuteSqlCommand重载:
public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
RawSqlString sql, params object[] parameters); // 1
public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
RawSqlString sql, IEnumerable<object> parameters); // 2
public static int ExecuteSqlCommand(this DatabaseFacade databaseFacade,
FormattableString sql); // 3
Run Code Online (Sandbox Code Playgroud)
在 EF Core 3.x 中映射到
public static int ExecuteSqlRaw(this DatabaseFacade databaseFacade,
string sql, params object[] parameters); // 1
public static int ExecuteSqlRaw(this DatabaseFacade databaseFacade,
string sql, IEnumerable<object> parameters); // 2
public static int ExecuteSqlInterpolated(this DatabaseFacade databaseFacade,
FormattableString sql); // 3
Run Code Online (Sandbox Code Playgroud)
在功能上它们是完全等效的。Raw重载支持与 v2.x 重载 #1 和 #2 相同的占位符和参数值(命名和未命名)。并且Interpolated具有与 v2.x 重载 #3 完全相同的行为。
重命名方法并为内插和非内插sql参数使用不同名称的原因是 v2.x 重载 #1 和 #3 的 C# 编译时重载决议。有时它在意图使用另一个时选择插值,反之亦然。使用单独的名称可以使意图明确。
您可以在 EF Core 3.0 Breaking Changes - FromSql、ExecuteSql 和 ExecuteSqlAsync 已重命名中阅读有关推理的更多信息。
有关支持的参数占位符、名称和值的信息可以在原始 SQL 查询 - 传递参数中找到。
但是要回答您的具体问题,如果现有的 v2.x 代码是
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);
Run Code Online (Sandbox Code Playgroud)
然后将其更改为ExecuteSqlRaw.
如果是
context.Database.ExecuteSqlCommand($"DELETE FROM Table WHERE ID = {id}");
Run Code Online (Sandbox Code Playgroud)
然后将其更改为ExecuteSqlInterpolated.
我没有看到文档在哪里定义了 userSuppliedSearchTerm 变量的内容或其类型,并且我正在努力了解它如何明智地成为 SQL 块(字符串 userSuppliedSearchTerm = "WHERE id = 123"; 并烘焙在值?SQL 注入?)或单个原始值(int userSuppliedSearchTerm = 123),那么这是否意味着它是某种指定数据库列名称和值的自定义类型?EFCore 如何知道要查询表中的哪一列?EFCore 是否会解决括号中出现的语法错误?EFCore 理解查询时必须使用括号吗?
与 EF Core 无关
文档选择使用表值函数dbo.SearchBlogs来演示原始 SQL 查询的使用,SELECT * FROM [dbo].[SearchBlogs]({0})合法的 SQL 也是如此,因为它SearchBlogs是一个函数,而不是表/视图 - 只是我链接的文档中没有提到它
| 归档时间: |
|
| 查看次数: |
26623 次 |
| 最近记录: |