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

ASP.NET Core 6.0构建MySQL 8.0存储过程动态结果Model类

解决方案:适配MySQL动态结果集的ASP.NET Core实现

针对存储过程返回动态行列的问题,提供三种可行方案:

方案1:使用DataTable直接接收动态结果

DataTable可以自动适配任意结构的返回集,无需提前定义Model,适合快速处理动态数据:

using MySqlConnector;
using System.Data;

public async Task<DataTable> GetUserCheckInsAsync(int year, int month, string param)
{
    using var connection = new MySqlConnection("你的数据库连接字符串");
    await connection.OpenAsync();
    
    using var command = new MySqlCommand("rep_getusercheckinsperday", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@year", year);
    command.Parameters.AddWithValue("@month", month);
    command.Parameters.AddWithValue("@param", param);
    
    var dataTable = new DataTable();
    using var adapter = new MySqlDataAdapter(command);
    adapter.Fill(dataTable);
    
    return dataTable;
}

拿到DataTable后,可直接绑定到前端表格控件,或通过遍历dataTable.Rows和dataTable.Columns手动处理数据。

方案2:使用动态类型/ExpandoObject接收

如果希望用对象形式操作数据,可借助ExpandoObject或动态类型,配合Dapper简化操作:

先安装Dapper和MySqlConnector NuGet包,再实现代码:

using Dapper;
using MySqlConnector;
using System.Dynamic;

public async Task<List<dynamic>> GetUserCheckInsDynamicAsync(int year, int month, string param)
{
    using var connection = new MySqlConnection("你的数据库连接字符串");
    await connection.OpenAsync();
    
    var results = await connection.QueryAsync("CALL rep_getusercheckinsperday(@year, @month, @param)", 
        new { year, month, param });
    
    return results.ToList();
}

// 原生ADO.NET场景下用ExpandoObject手动构建
public async Task<List<ExpandoObject>> GetUserCheckInsExpandoAsync(int year, int month, string param)
{
    using var connection = new MySqlConnection("你的数据库连接字符串");
    await connection.OpenAsync();
    
    using var command = new MySqlCommand("rep_getusercheckinsperday", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@year", year);
    command.Parameters.AddWithValue("@month", month);
    command.Parameters.AddWithValue("@param", param);
    
    using var reader = await command.ExecuteReaderAsync();
    var resultList = new List<ExpandoObject>();
    
    while (await reader.ReadAsync())
    {
        var expando = new ExpandoObject();
        var expandoDict = (IDictionary<string, object>)expando;
        
        for (int i = 0; i < reader.FieldCount; i++)
        {
            expandoDict.Add(reader.GetName(i), reader.IsDBNull(i) ? null : reader[i]);
        }
        
        resultList.Add(expando);
    }
    
    return resultList;
}

使用动态类型时,可通过dynamicItem.User或dynamicItem.Day1这类形式直接访问属性(属性名对应返回列名)。

方案3:重构存储过程返回固定结构

如果有权限修改存储过程,建议将动态列转换为固定行结构,这样就能复用你原有的DBGetMyGuidesReportsbyDay类。

修改存储过程,让它返回三列:User、Day、Total,例如原本返回User, Day1, Day2, ..., Day30的结构,改为返回多行:

DayTotal
15
23
......

修改后,原Model就能直接适配,用EF Core或Dapper查询都很方便:

// Dapper查询示例
public async Task<List<DBGetMyGuidesReportsbyDay>> GetUserCheckInsFixedAsync(int year, int month, string param)
{
    using var connection = new MySqlConnection("你的数据库连接字符串");
    await connection.OpenAsync();
    
    var results = await connection.QueryAsync<DBGetMyGuidesReportsbyDay>(
        "CALL rep_getusercheckinsperday(@year, @month, @param)", 
        new { year, month, param });
    
    return results.ToList();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:32:19