首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EFCore3.1 ExecuteSqlRaw / ExecuteSqlRawAsync是否取代ExecuteSqlCommand / ExecuteSqlCommandAsync?

EFCore3.1 ExecuteSqlRaw / ExecuteSqlRawAsync是否取代ExecuteSqlCommand / ExecuteSqlCommandAsync?
EN

Stack Overflow用户
提问于 2020-01-09 11:11:19
回答 2查看 50.6K关注 0票数 30

升级到EFCore 3.1时,出现了过时的警告:

警告'RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync(DatabaseFacade,CS0618 RawSqlString,params object[])“过时了:对于使用普通字符串的SQL查询的异步执行,使用ExecuteSqlRawAsync代替。对于使用内插字符串语法创建参数的SQL查询的异步执行,请使用ExecuteSqlInterpolatedAsync代替。” 警告'RelationalDatabaseFacadeExtensions.ExecuteSqlCommand(DatabaseFacade,CS0618 RawSqlString,params object[])“过时了:”对于使用普通字符串执行的SQL查询,使用ExecuteSqlRaw代替。对于使用内插字符串语法创建参数的SQL查询,请使用ExecuteSqlInterpolated代替。

它们所涉及的旧代码如下:

代码语言:javascript
运行
复制
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);
await context.Database.ExecuteSqlCommandAsync("DELETE FROM Table2 WHERE ID = @p0", id);

参考精细手册,完全没有讨论典型的Server参数@somename,实际上,我甚至不知道文档中的示例代码(在表名后面显示括号)是如何有效的SQL语法:

代码语言:javascript
运行
复制
context.Database.ExecuteSqlRaw("SELECT * FROM [dbo].[SearchBlogs]({0})", userSuppliedSearchTerm)

我没有看到文档在哪里定义了userSuppliedSearchTerm变量的内容或它的类型,而且我很难理解它是如何明智地成为SQL的核心(string userSuppliedSearchTerm = "WHERE id = 123";中有烘焙值吗?)SQL注入?)或者一个原语值(int userSuppliedSearchTerm = 123),这是否意味着它是某种自定义类型,指定了db列名和值?EFCore如何知道表中的哪一列将被查询?EFCore是否整理了括号所显示的语法错误?EFCore是否必须使用括号才能理解查询?

最后,我的问题是:考虑到我的ExecuteSqlCommand代码是有意义的,而ExecuteSqlRaw的文档没有什么意义/似乎解释得很糟糕,那么我们该如何从这个工作代码出发:

代码语言:javascript
运行
复制
var id = 123;
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);

使用ExecuteSqlRaw?

代码语言:javascript
运行
复制
SomeType x = ???;
context.Database.ExecuteSqlRaw("???", x);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-09 16:27:05

我没有看到文档在哪里定义了userSuppliedSearchTerm变量的内容或它的类型,而且我很难理解它是如何明智地成为SQL的核心(string userSuppliedSearchTerm = "WHERE = 123";使用烘焙值吗?SQL注入?)或者一个原语值(int userSuppliedSearchTerm = 123),这是否意味着它是某种自定义类型,指定了db列名和值?EFCore如何知道表中的哪一列将被查询?EFCore是否整理了括号所显示的语法错误?EFCore是否必须使用括号才能理解查询?

与EF核心无关

文档选择使用一个表值函数dbo.SearchBlogs来演示原始SQL查询的用法,因此SELECT * FROM [dbo].[SearchBlogs]({0})是合法的SearchBlogs,因为SearchBlogs是一个函数,而不是一个表/视图--只是在我链接的文档中没有提到它。

票数 4
EN

Stack Overflow用户

发布于 2020-01-09 16:05:48

规则很简单。

EFCore2.x有3个ExecuteSqlCommand重载:

代码语言:javascript
运行
复制
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

在EF Core 3.x中映射到

代码语言:javascript
运行
复制
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

在功能上,它们是完全等价的。Raw重载支持与v2.x重载#1和#2相同的占位符和参数值(命名和未命名)。Interpolated具有与v2.x重载#3完全相同的行为。

将该方法重命名并使用不同的名称用于插值和非插值sql参数的原因是v2.x重载#1和#3的C#编译时重载解析。有时,当打算使用另一个重载时,它选择插值,反之亦然。有单独的名字可以清楚地表明意图。

您可以阅读更多关于EFCore3.0ClingChange- FromSql、ExecuteSql和ExecuteSqlAsync已被重命名中的推理的文章。

有关受支持的参数占位符、名称和值的信息可以在原始SQL查询-传递参数中找到。

但是要回答您的具体问题,如果现有的v2.x代码是

代码语言:javascript
运行
复制
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);

然后将其更改为ExecuteSqlRaw

如果是

代码语言:javascript
运行
复制
context.Database.ExecuteSqlCommand($"DELETE FROM Table WHERE ID = {id}");

然后将其更改为ExecuteSqlInterpolated

票数 51
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59662673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档