You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 3.1中ExecuteSqlRaw能否替代ExecuteSqlCommand?及迁移问题

解决EF Core 3.1中ExecuteSqlCommand过时的问题:迁移指南与文档疑问解答

嗨,我刚踩过这个坑,给你详细说下怎么迁移代码,还有你对官方文档的疑问也一起掰扯清楚~

一、把原有代码迁移到ExecuteSqlRaw的正确写法

你的原有代码是:

var id = 123;
context.Database.ExecuteSqlCommand("DELETE FROM Table WHERE ID = @p0", id);

迁移到ExecuteSqlRaw有两种稳妥的方式,完全兼容SQL Server的参数习惯:

方式1:沿用位置占位符(最省心的迁移)

直接把ExecuteSqlCommand换成ExecuteSqlRaw就行,写法和原来几乎一样:

var id = 123;
context.Database.ExecuteSqlRaw("DELETE FROM Table WHERE ID = @p0", id);

这种方式不需要改SQL语句和参数传递逻辑,直接替换方法名就能解决过时警告。

方式2:使用SQL Server风格的命名参数(更清晰)

如果你习惯用@Id这种命名参数(而不是@p0),可以配合SqlParameter来明确参数名,这样多参数场景下更不容易出错:

var id = 123;
context.Database.ExecuteSqlRaw(
    "DELETE FROM Table WHERE ID = @Id", 
    new SqlParameter("@Id", id)
);

这里要注意,参数名必须和SQL里的占位符完全一致(包括@符号),EF Core会自动帮你绑定。

二、关于官方文档的疑问解答

你提到官方文档没提SQL Server的@xxx参数,其实是因为EF Core是跨数据库框架,@p0这类位置占位符是所有数据库都支持的通用写法,而@Id这种命名参数是SQL Server(以及部分其他数据库)的特定语法。

官方文档没重点讲命名参数,主要是想优先展示跨数据库通用的方案,但EF Core完全支持SQL Server的命名参数用法,只要你用SqlParameter显式声明参数名就可以正常工作。

另外,官方还推荐了ExecuteSqlInterpolated(异步版ExecuteSqlInterpolatedAsync),这个方法用字符串插值的写法更直观,而且完全安全(不会有SQL注入风险,因为EF Core会自动把插值转换成参数):

var id = 123;
context.Database.ExecuteSqlInterpolated($"DELETE FROM Table WHERE ID = {id}");

这种写法看起来像是直接拼接字符串,但实际上EF Core会把{id}转换成对应的参数,和参数化查询的安全性一致,可读性反而更高。

为什么要拆分这两个方法?

原来的ExecuteSqlCommand既支持位置参数又支持插值写法,容易让开发者混淆,甚至不小心写出直接拼接字符串的危险代码。拆分后:

  • ExecuteSqlRaw专门处理原生SQL字符串(带占位符),适合需要精确控制SQL语句的场景
  • ExecuteSqlInterpolated专门处理插值字符串,兼顾可读性和安全性

这样职责更清晰,也能避免SQL注入的风险。

内容的提问来源于stack exchange,提问作者Caius Jard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 08:59:09