如何通过ASP.NET Core Web API获取SQL Server存储过程返回的多结果集
问题根因
- 你当前使用的
FromSqlRaw方法默认只会读取存储过程返回的第一个结果集,MultipleActiveResultSets=True配置是用于支持同一连接下并发多个活动查询的场景,和读取存储过程返回的多个结果集没有关系。 - 你的DbContext配置存在笔误:
CrimeList对应的DbSet泛型类型错误写成了Outputs,就算后续读取第二个结果集也无法完成映射。 - 原有存储过程调用方式直接拼接SQL字符串,存在严重的SQL注入风险。
解决方案
步骤1:修正DbContext配置
把CrimeList对应的DbSet类型改为正确的实体类:
public class CallSPDBContext : DbContext { public CallSPDBContext(DbContextOptions<CallSPDBContext> options):base(options) { } public DbSet<MoveHereAPI.Models.DB.Outputs> Outputs { get; set; } // 修正此处的泛型类型 public DbSet<MoveHereAPI.Models.DB.CrimeList> CrimeList { get; set; } }
步骤2:新增多结果集返回实体
创建一个复合实体类用于同时返回两个结果集的数据:
public class CrimeDataResult { // 第一个结果集:统计数据 public List<Outputs> Statistics { get; set; } // 第二个结果集:犯罪明细列表 public List<CrimeList> CrimeDetails { get; set; } }
步骤3:重写Controller查询逻辑
使用DbDataReader的NextResult方法读取多个结果集,同时改为参数化查询避免注入风险:
[HttpPost] public async Task<ActionResult<CrimeDataResult>> GetOutputs(Input input) { await using var command = _context.Database.GetDbConnection().CreateCommand(); command.CommandText = "usp_GetCrimeData"; command.CommandType = System.Data.CommandType.StoredProcedure; // 参数化查询,避免SQL注入 command.Parameters.Add(new SqlParameter("@Postcode", input.Postcode)); await _context.Database.OpenConnectionAsync(); await using var reader = await command.ExecuteReaderAsync(); // 读取第一个结果集,映射为Outputs var statistics = _context.Outputs .FromSql($"SELECT * FROM {reader}") .ToList(); // 切换到第二个结果集 await reader.NextResultAsync(); // 读取第二个结果集,映射为CrimeList var crimeDetails = _context.CrimeList .FromSql($"SELECT * FROM {reader}") .ToList(); return new CrimeDataResult { Statistics = statistics, CrimeDetails = crimeDetails }; }
注意事项
- 存储过程返回结果集的顺序需要和代码读取顺序一致,必须先返回统计结果集,再返回犯罪明细结果集。
- 不需要保留
MultipleActiveResultSets=True配置,该配置对你的场景没有作用。
内容的提问来源于stack exchange,提问作者KnifeWrench
相关产品推荐
相关产品推荐

