EF Core 的
FromSqlInterpolated是安全执行参数化原生 SQL 查询的推荐方式,它自动处理参数防注入,比拼接字符串或
FromSqlRaw更安全、更简洁。
基本用法:查询实体集合
适用于返回映射到实体(如
Blog)的查询结果。SQL 中用
{} 插入参数,EF Core 自动转为命名参数并传递值:
var minRating = 4;
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM Blogs WHERE Rating >= {minRating}")
.ToList();注意:
FromSqlInterpolated必须作用于 DbSet(如
context.Blogs),且返回类型需与实体匹配;SQL 必须返回所有实体属性(或至少不缺失主键和必需字段)。
支持复杂参数:变量、表达式、null 值
可插入本地变量、属性、方法调用结果,甚至
null—— EF Core 会正确映射为数据库
NULL:
var name = "MS"; var blogs = context.Blogs.FromSqlInterpolated($"SELECT * FROM Blogs WHERE Name LIKE {%name%}");
var now = DateTime.UtcNow; var recent = context.Posts.FromSqlInterpolated($"SELECT * FROM Posts WHERE CreatedAt > {now.AddDays(-7)}");
string? keyword = null; var posts = context.Posts.FromSqlInterpolated($"SELECT * FROM Posts WHERE Title LIKE {keyword ?? "%"}");
配合 AsNoTracking 和 ToListAsync 提升性能
若只需读取数据不修改,加
AsNoTracking()减少变更跟踪开销;异步场景优先用
ToListAsync():
var blogs = await context.Blogs
.FromSqlInterpolated($"SELECT * FROM Blogs WHERE IsActive = {true}")
.AsNoTracking()
.ToListAsync();⚠️ 注意:不能在
FromSqlInterpolated后再写 LINQ 方法(如
.Where()或
.OrderBy()),否则会触发客户端评估或报错 —— 过滤/排序应写在 SQL 内。
执行非查询语句(INSERT/UPDATE/DELETE)用 ExecuteSqlInterpolated
FromSqlInterpolated仅用于
SELECT。执行命令请用
ExecuteSqlInterpolated:
var name = "New Blog";
var rowsAffected = await context.Database
.ExecuteSqlInterpolatedAsync($"INSERT INTO Blogs (Name, Rating) VALUES ({name}, {5})");它返回影响行数(
int),也支持事务和异步操作。
基本上就这些 —— 记住核心:用插值字符串 + 大括号传参,EF Core 自动参数化,既简洁又安全。
