EF Core 7中FromSql误将SQL查询识别为存储过程如何解决?
问题
在ASP.NET Core项目中使用EF Core 7时,调用FromSql执行原生SELECT查询,EF Core误将SQL语句识别为存储过程名称,抛出异常:
Microsoft.Data.SqlClient.SqlException Could not find stored procedure 'SELECT * FROM dbo.Country'
测试语句SELECT * FROM dbo.Country在SSMS中可正常运行,但找不到能指定输入为查询语句而非存储过程的FromSql重载方法。报错代码如下:
public async Task<List<T>> RunRawSql(string query) { try { var a = _context.Set<T>().FromSql($"{query}"); return a.ToList(); } catch (Exception ex) { return null; } }
解决方法
1. 使用FromSqlRaw执行原生SQL查询
问题根源在于:直接用字符串插值$"{query}"传入FromSql时,EF Core会将整个字符串当作存储过程名称处理。改用FromSqlRaw方法可明确执行原生SQL查询语句:
修正后的代码:
public async Task<List<T>> RunRawSql(string query) { try { var result = _context.Set<T>().FromSqlRaw(query); return await result.ToListAsync(); // 修正异步方法未await的问题 } catch (Exception ex) { return null; } }
2. 参数化查询(避免SQL注入)
如果查询包含动态参数,禁止直接拼接字符串,需用参数化方式保证安全:
- 方式一:使用
FromSqlInterpolated自动处理参数
public async Task<List<Country>> GetCountryById(int countryId) { return await _context.Set<Country>() .FromSqlInterpolated($"SELECT * FROM dbo.Country WHERE Id = {countryId}") .ToListAsync(); }
- 方式二:使用
FromSqlRaw配合SqlParameter
public async Task<List<Country>> GetCountryById(int countryId) { var parameter = new SqlParameter("@CountryId", countryId); return await _context.Set<Country>() .FromSqlRaw("SELECT * FROM dbo.Country WHERE Id = @CountryId", parameter) .ToListAsync(); }
内容的提问来源于stack exchange,提问作者emrebener
相关产品推荐
相关产品推荐

