ASP.NET Core 6 MVC与EF Core 6执行未映射存储过程的问题
EF Core 6调用未映射存储过程的解决方案
问题说明
基于ASP.NET Core 6 MVC和Entity Framework Core 6开发测试应用,已通过模型生成数据库,新增了未在模型中映射的存储过程,但调用时出现两个问题:
- 使用
SqlQuery时提示无法将string转换为System.FormattableString - 使用
SqlQueryRaw时代码无法正常执行并获取结果
正确实现方案
1. 先明确EF Core 6的API规则
EF Core 6中,Database.SqlQuery<T>要求传入格式化字符串(FormattableString),直接传普通字符串会触发类型转换错误;SqlQueryRaw用于原生SQL执行,但必须主动触发结果获取(比如调用ToList())才能拿到数据。
2. 修复仓储层代码
方式一:使用SqlQuery(格式化字符串写法)
用$""语法将SQL转为格式化字符串,同时正确处理返回结果:
public List<TEntity> GetAllSP() { return _dbContext.Database.SqlQuery<TEntity>($"EXEC SP").ToList(); }
方式二:使用SqlQueryRaw(原生SQL写法)
直接传入原生SQL,注意必须调用ToList()执行查询并获取结果:
public List<TEntity> GetAllSP() { return _dbContext.Database.SqlQueryRaw<TEntity>("EXEC SP").ToList(); }
3. 关键注意事项
- 确保存储过程
SP返回的字段名称、数据类型与TEntity(比如AspNetUser)的属性完全匹配,否则EF Core无法自动映射 - 如果存储过程返回的是自定义结果集(和现有实体结构不匹配),需要新建对应的DTO类来接收结果,不能直接用现有实体
- 若需要传递参数,必须用参数化查询避免SQL注入,示例如下:
// 带参数的存储过程调用示例 public List<TEntity> GetUserByIdSP(int userId) { return _dbContext.Database.SqlQueryRaw<TEntity>( "EXEC SP_GetUserById @UserId", new SqlParameter("@UserId", userId) ).ToList(); }
完整修正后的仓储层代码
namespace COBRAAuthentication.Repository.Repositories { public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class, IEntity { private readonly CobraDbContext _dbContext; public GenericRepository(CobraDbContext dbContext) { _dbContext = dbContext; } public List<TEntity> GetAllSP() { // 二选一即可 // 方式一:SqlQuery格式化字符串写法 return _dbContext.Database.SqlQuery<TEntity>($"EXEC SP").ToList(); // 方式二:SqlQueryRaw原生SQL写法 // return _dbContext.Database.SqlQueryRaw<TEntity>("EXEC SP").ToList(); } } }
内容的提问来源于stack exchange,提问作者Diego
相关产品推荐
相关产品推荐

