如何将DapperRow列表转换为强类型对象列表?
解决Dapper泛型方法映射强类型列表问题
问题根源
你原代码的核心问题是错误地将List<ReferralModel>作为泛型参数传入ExecuteQueryAsync。Dapper的QueryAsync<T>方法中,T应该是单个实体类型(比如ReferralModel),而非集合类型。当你传入List<ReferralModel>时,Dapper会尝试把数据库的每一行数据映射成List<ReferralModel>,这显然不符合数据结构,最终返回的是无法正确转换的DapperRow集合,导致调用ToList()时报错。
修正方案
1. 重构泛型方法
将方法返回类型从dynamic改为IEnumerable<T>,保留Dapper原生的返回类型,同时明确泛型参数为实体类:
public async Task<IEnumerable<T>> ExecuteQueryAsync<T>(string sqlStatement) { using (var connection = new SqlConnection(_connectionString)) { await connection.OpenAsync(); return await connection.QueryAsync<T>(sqlStatement); } }
2. 正确调用方法
- 查询多行数据:传入实体类作为泛型参数,直接对返回的
IEnumerable<T>调用ToList()即可:
var sqlStatement = $@"Select * from ClientReferral"; var retVal = await _dapperHelper.ExecuteQueryAsync<ReferralModel>(sqlStatement); return retVal.ToList(); // 此处不再报错
- 查询单行数据:同样传入实体类参数,通过
FirstOrDefault()获取单条结果:
var sqlStatement = $@"Select * from ClientReferral where id = 1"; var retVal = await _dapperHelper.ExecuteQueryAsync<ReferralModel>(sqlStatement); var singleReferral = retVal.FirstOrDefault();
3. 可选:封装更直观的专用方法
如果希望方法直接返回列表或单条数据,可以封装两个专用方法,提升代码可读性:
// 返回多行列表 public async Task<List<T>> ExecuteQueryListAsync<T>(string sqlStatement) { using (var connection = new SqlConnection(_connectionString)) { await connection.OpenAsync(); var result = await connection.QueryAsync<T>(sqlStatement); return result.ToList(); } } // 返回单行数据(无结果时返回null) public async Task<T?> ExecuteQuerySingleAsync<T>(string sqlStatement) where T : class { using (var connection = new SqlConnection(_connectionString)) { await connection.OpenAsync(); var result = await connection.QueryAsync<T>(sqlStatement); return result.FirstOrDefault(); } }
调用示例:
// 多行查询 var referralList = await _dapperHelper.ExecuteQueryListAsync<ReferralModel>(sqlStatement); // 单行查询 var singleReferral = await _dapperHelper.ExecuteQuerySingleAsync<ReferralModel>(sqlStatement);
补充说明
Dapper会自动完成DapperRow到强类型对象的映射,只要你的实体类属性名和数据库列名大小写不敏感匹配即可(比如数据库列ClientName和实体属性ClientName自动对应)。如果列名和属性名不一致,可以通过[Column]特性指定映射关系。
内容的提问来源于stack exchange,提问作者CodeMan03
相关产品推荐
相关产品推荐

