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

如何将PetaPocoHelper的ExecuteReader转为List[C#]?存储过程数据存List异常

我来帮你搞定这个问题!看起来你在从存储过程获取多结果集的时候,只把第一组数据存进List了,剩下的数据集完全没被处理对吧?先把你提到的相关内容整理清楚,再一步步解决~


1. 你的现有代码与结果

1.1 存储过程示例

-- 假设你的存储过程结构如下(可根据实际场景调整)
CREATE PROCEDURE GetMultiDatasetData
AS
BEGIN
    -- 第一个结果集:活跃用户信息
    SELECT UserId, UserName FROM Users WHERE IsActive = 1;
    -- 第二个结果集:近1个月订单记录
    SELECT OrderId, UserId, OrderDate FROM Orders WHERE OrderDate >= DATEADD(month, -1, GETDATE());
END

1.2 C# List填充实体类

// 用户信息实体
public class UserInfo
{
    public int UserId { get; set; }
    public string UserName { get; set; }
}

// 订单信息实体
public class OrderInfo
{
    public int OrderId { get; set; }
    public int UserId { get; set; }
    public DateTime OrderDate { get; set; }
}

// 多结果集封装容器
public class MultiDataResult
{
    public List<UserInfo> Users { get; set; } = new List<UserInfo>();
    public List<OrderInfo> Orders { get; set; } = new List<OrderInfo>();
}

1.3 有问题的C#业务代码

public MultiDataResult GetDataFromStoredProc()
{
    var result = new MultiDataResult();
    string connectionString = "你的数据库连接字符串";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = new SqlCommand("GetMultiDatasetData", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();

            // 仅读取了第一个结果集
            while (reader.Read())
            {
                result.Users.Add(new UserInfo
                {
                    UserId = (int)reader["UserId"],
                    UserName = reader["UserName"].ToString()
                });
            }
            // 完全没处理第二个结果集!
            reader.Close();
        }
    }
    return result;
}

1.4 当前ReturnJSON返回结果

{
  "Users": [
    {"UserId": 1, "UserName": "Alice"},
    {"UserId": 2, "UserName": "Bob"}
  ],
  "Orders": []
}

1.5 SQL Server Management Studio执行结果

执行存储过程后,SSMS显示两组结果:

  • 第一组:2条活跃用户记录
  • 第二组:5条近1个月的订单记录

1.6 期望的JSON返回格式

{
  "Users": [
    {"UserId": 1, "UserName": "Alice"},
    {"UserId": 2, "UserName": "Bob"}
  ],
  "Orders": [
    {"OrderId": 101, "UserId": 1, "OrderDate": "2024-05-01T00:00:00"},
    {"OrderId": 102, "UserId": 2, "OrderDate": "2024-05-05T00:00:00"},
    {"OrderId": 103, "UserId": 1, "OrderDate": "2024-05-10T00:00:00"},
    {"OrderId": 104, "UserId": 2, "OrderDate": "2024-05-15T00:00:00"},
    {"OrderId": 105, "UserId": 1, "OrderDate": "2024-05-20T00:00:00"}
  ]
}

2. 问题根因

你的代码只处理了第一个结果集,没有调用SqlDataReader.NextResult()方法切换到下一个结果集,导致后续数据集的内容完全没被读取和存入List。


3. 修复方案:处理多结果集

修改业务代码,读完第一个结果集后调用NextResult()切换,再读取第二个结果集:

public MultiDataResult GetDataFromStoredProc()
{
    var result = new MultiDataResult();
    string connectionString = "你的数据库连接字符串";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = new SqlCommand("GetMultiDatasetData", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();
            // 用using包裹reader,自动释放资源,无需手动Close
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                // 读取第一个结果集:用户数据
                while (reader.Read())
                {
                    result.Users.Add(new UserInfo
                    {
                        UserId = (int)reader["UserId"],
                        UserName = reader["UserName"].ToString()
                    });
                }

                // 切换到第二个结果集,成功切换后读取订单数据
                if (reader.NextResult())
                {
                    while (reader.Read())
                    {
                        result.Orders.Add(new OrderInfo
                        {
                            OrderId = (int)reader["OrderId"],
                            UserId = (int)reader["UserId"],
                            OrderDate = (DateTime)reader["OrderDate"]
                        });
                    }
                }
            }
        }
    }
    return result;
}

4. 额外优化建议

  1. 自动处理多结果集循环:如果存储过程返回3个及以上结果集,可以用循环遍历所有结果集:
do
{
    // 可通过reader.GetSchemaTable()获取列信息,判断当前结果集对应哪个实体类
    // 比如根据列名判断是用户还是订单,再填充对应List
} while (reader.NextResult());
  1. 用ORM简化代码:推荐使用Dapper框架,它的QueryMultiple()方法可以一键读取多结果集,代码更简洁:
using (var multi = conn.QueryMultiple("GetMultiDatasetData", commandType: CommandType.StoredProcedure))
{
    var users = multi.Read<UserInfo>().ToList();
    var orders = multi.Read<OrderInfo>().ToList();
    return new MultiDataResult { Users = users, Orders = orders };
}

内容的提问来源于stack exchange,提问作者Carlos Miranda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:09:31