FromSqlInterpolated 是 EF Core 安全执行参数化原生 SQL 查询的推荐方式,自动防注入;支持变量、表达式、null 插值;仅用于 SELECT,非查询语句用 ExecuteSqlInterpolated。

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 自动参数化,既简洁又安全。










