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的结构,改为返回多行:
| Day | Total |
|---|---|
| 1 | 5 |
| 2 | 3 |
| ... | ... |
修改后,原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
相关产品推荐
相关产品推荐

