You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL存储过程多结果集映射到C# View Model类

解决SQL多结果集映射到C# ViewModel的问题

嘿,我来帮你搞定这个多结果集映射的问题!你当前用的Database.SqlQuery<T>方法只能处理单个结果集,而你的存储过程返回了多个结果集(对应ViewModel里的total值、大洲统计列表和国家统计列表),所以得换一种方式手动读取每个结果集。下面是具体的实现步骤:

1. 确保子模型类与存储过程返回字段匹配

首先,你需要明确ContinentByPercentage和CountryByMembers的字段定义,要和存储过程返回的列名完全对应(大小写敏感,除非数据库配置了不区分)。比如:

public class ContinentByPercentage
{
    public string ContinentName { get; set; } // 替换成存储过程返回的实际列名
    public decimal Percentage { get; set; }
    // 其他对应字段,比如MemberCount等
}

public class CountryByMembers
{
    public string CountryName { get; set; } // 替换成存储过程返回的实际列名
    public int TotalMembers { get; set; }
    // 其他对应字段
}

2. 手动读取多结果集的实现代码

我们需要直接使用DbConnection和DbDataReader来依次读取每个结果集,代码如下:

// 初始化目标ViewModel
var memberStats = new MemberStatsByTopCountryViewModel();

using (var connection = Database.Connection)
{
    // 确保连接处于打开状态
    if (connection.State != ConnectionState.Open)
        connection.Open();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "sp_members";
        command.CommandType = CommandType.StoredProcedure;

        // 执行存储过程并获取数据读取器
        using (var reader = command.ExecuteReader())
        {
            // 读取第一个结果集:Total成员数(单行单列)
            if (reader.Read())
            {
                // 用GetOrdinal获取列索引,避免列顺序变化导致的错误
                memberStats.total = reader.GetInt32(reader.GetOrdinal("Total"));
            }

            // 切换到第二个结果集:大洲占比列表
            reader.NextResult();
            var continentList = new List<ContinentByPercentage>();
            while (reader.Read())
            {
                continentList.Add(new ContinentByPercentage
                {
                    ContinentName = reader.GetString(reader.GetOrdinal("ContinentName")),
                    Percentage = reader.GetDecimal(reader.GetOrdinal("Percentage"))
                    // 映射其他字段
                });
            }
            memberStats.continentByPercentage = continentList;

            // 切换到第三个结果集:国家成员数列表
            reader.NextResult();
            var countryList = new List<CountryByMembers>();
            while (reader.Read())
            {
                countryList.Add(new CountryByMembers
                {
                    CountryName = reader.GetString(reader.GetOrdinal("CountryName")),
                    TotalMembers = reader.GetInt32(reader.GetOrdinal("TotalMembers"))
                    // 映射其他字段
                });
            }
            memberStats.countrybyMembers = countryList;
        }
    }
}

// 现在memberStats就包含了所有结果集的数据

关键注意事项

  • 列名匹配:必须确保模型类的属性名和存储过程返回的列名完全一致,或者通过GetOrdinal指定正确的列索引(推荐后者,更稳定)。
  • 资源释放:所有DbConnection、DbCommand和DbDataReader都要用using语句包裹,确保资源自动释放。
  • EF版本兼容:如果是EF Core,代码略有不同,需要用Database.GetDbConnection()来获取底层连接,但核心逻辑一致。

内容的提问来源于stack exchange,提问作者Arun kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:15:20