EF Core 6.0.6连接MS SQL时如何执行原生SQL命令?
问题原因
你检索到的Query<T>()、ExecuteSqlCommand()、SqlQuery()都是EF Core 2.x及更早版本的旧API,从EF Core 3.0开始这些接口就被逐步重构替换,到6.0版本已经完全移除,直接调用必然会提示方法不存在。
你调用GetDbConnection()失败通常是缺少对应命名空间引用,该扩展方法属于关系数据库提供程序的扩展集,添加using Microsoft.EntityFrameworkCore;即可正常识别。
EF Core 6.0.6 执行原生SQL的可用实现
根据不同使用场景选择对应API即可:
- 场景1:查询结果为已映射的实体类型(即你当前使用的、对应Questions表的Question实体)
这类查询直接在对应实体的DbSet<T>上调用原生SQL查询方法即可,支持后续跟着Include、Where等LINQ算子:// 优先使用插值版本,自动做SQL参数化,防止注入 var questionList = db.Questions .FromSqlInterpolated($"SELECT * FROM Questions WHERE Score > {minScore}") .Include(q => q.Answers) .ToList(); // 调用存储过程、固定SQL语句时可使用Raw版本,手动传入参数 var idParam = new SqlParameter("@targetId", questionId); var singleQuestion = db.Questions .FromSqlRaw("SELECT * FROM Questions WHERE Id = @targetId", idParam) .AsNoTracking() .FirstOrDefault(); - 场景2:执行增删改、DDL等非查询类SQL
这类操作通过DatabaseFacade执行,返回值为SQL执行影响的行数:var affectedCount = db.Database.ExecuteSqlInterpolated( $"DELETE FROM Questions WHERE CreateTime < {expireTime}"); - 场景3:查询结果为未注册实体映射的自定义类型(比如统计结果、多表联查的精简DTO)
EF Core 6.0原生支持直接查询任意CLR类型,不需要提前在DbContext中添加对应的DbSet配置:// 自定义查询结果DTO public class QuestionStatDto { public int CategoryId { get; set; } public int TotalCount { get; set; } } var statResult = db.Database .SqlQuery<QuestionStatDto>($"SELECT CategoryId, COUNT(1) TotalCount FROM Questions GROUP BY CategoryId") .ToList();
注意:使用带Raw后缀的方法时禁止直接拼接用户输入到SQL字符串中,必须通过SQL参数传入,避免出现SQL注入漏洞。
内容的提问来源于stack exchange,提问作者Wiesel Leonid
相关产品推荐
相关产品推荐

