Entity Framework Core 2.0.2的FromSql方法存在Bug,寻求技术帮助
解决Entity Framework Core 2.0.2中FromSql处理存储过程输出参数的Bug
最近踩了Entity Framework Core 2.0.2版本的一个坑——它的FromSql方法在执行带输出参数的存储过程时,没法正确获取输出参数的值。折腾了半天后,我自己写了个通用函数来解决这个问题,既能执行存储过程获取实体数据,又能准确拿到输出参数的结果:
public IDictionary<string, object> RunSql<T>(string spName, IList<SqlParameter> spParamList) where T : class { var result = new Dictionary<string, object>(); try { // 构造存储过程执行语句,给输出参数加上OUTPUT标记 string sqlCommand = $"{spName} " + string.Join(", ", spParamList.Select(p => p.ParameterName + (p.Direction == ParameterDirection.Output ? " OUTPUT" : ""))); // 执行存储过程,用AsNoTracking避免上下文追踪提升性能 var data = _context.Set<T>().AsNoTracking().FromSql(sqlCommand, spParamList.ToArray()).ToList(); // 提取所有输出/输入输出参数的值 var outputParams = spParamList.Where(p => p.Direction is ParameterDirection.Output or ParameterDirection.InputOutput) .ToDictionary(p => p.ParameterName, p => p.Value); // 将结果数据和输出参数存入字典返回 result["Data"] = data; result["OutputParameters"] = outputParams; } catch (Exception ex) { // 这里可以根据项目需求添加日志记录等异常处理 throw; } return result; }
关键点说明:
- 构造执行语句:必须给输出参数显式加上
OUTPUT关键字,否则存储过程不会返回这些参数的值 - 手动读取输出参数:EF Core 2.0.2的
FromSql执行完后不会自动填充输出参数的Value,所以必须在查询执行后手动遍历参数集合提取 - 封装返回结果:把实体数据和输出参数都放进字典里,调用者可以直接通过键名获取需要的内容
使用注意事项:
- 泛型
T必须和存储过程返回的结果集字段完全匹配,否则会出现映射错误 - 别忘了处理
ParameterDirection.InputOutput类型的参数,这类参数既接收输入也会返回输出值 - 如果不需要返回实体数据,可以修改函数逻辑,只返回输出参数集合
内容的提问来源于stack exchange,提问作者Boris
相关产品推荐
相关产品推荐

