能否用泛型集合替代多T泛型参数创建通用Dapper方法?
用灵活类型集合替代固定多泛型参数的Dapper多结果读取方法
你原来的代码确实实现了多泛型参数的方法,但固定的T1-T4限制了方法的灵活性——只能处理最多4种结果类型。要实现适配任意数量结果类型的通用方法,可以结合反射和Type数组来动态读取每个结果集,替代固定泛型参数的写法。
实现方案:动态读取任意数量的结果集
下面是一个通用方法,通过传入结果类型的数组,动态调用Dapper的Read<T>方法,返回对应类型的结果集合:
public static List<IEnumerable<object>> DapperMultiRead(string sql, params Type[] resultTypes) { // 假设conString是你的数据库连接字符串 using (var connection = new SqlConnection(conString)) using (var multi = connection.QueryMultiple(sql, null)) { var results = new List<IEnumerable<object>>(); foreach (var type in resultTypes) { // 获取GridReader的泛型Read<T>方法 var readMethod = typeof(SqlMapper.GridReader) .GetMethod("Read", Type.EmptyTypes) ?.MakeGenericMethod(type); if (readMethod == null) { results.Add(Enumerable.Empty<object>()); continue; } // 调用Read<T>并转换为IEnumerable<object> var result = readMethod.Invoke(multi, null) as IEnumerable<object>; results.Add(result?.ToList() ?? Enumerable.Empty<object>()); } return results; } }
使用示例
调用时传入SQL语句和需要读取的结果类型即可,后续可以将结果转换为具体类型的列表:
// 读取两个不同类型的结果集 var results = DapperMultiRead( "Select * from InventoryMaster;Select * from OrderMaster", typeof(InventoryMaster), typeof(OrderMaster) ); // 转换为具体类型的列表 var inventoryList = results[0].Cast<InventoryMaster>().ToList(); var orderList = results[1].Cast<OrderMaster>().ToList();
优缺点说明
- 优点:完全适配任意数量的结果类型场景,不需要为每种数量的泛型参数写重载方法。
- 缺点:使用了反射,相比直接写泛型方法有轻微的性能开销;返回结果需要手动转换为具体类型,失去了部分编译时类型安全。
替代方案:类型安全的重载方法
如果对性能和类型安全要求更高,可以针对常用的泛型参数数量写重载方法,比如:
// 2个结果类型的重载 public static (List<T1>, List<T2>) DapperMultiRead<T1, T2>(string sql) { using (var connection = new SqlConnection(conString)) using (var multi = connection.QueryMultiple(sql, null)) { return (multi.Read<T1>().ToList(), multi.Read<T2>().ToList()); } } // 3个结果类型的重载 public static (List<T1>, List<T2>, List<T3>) DapperMultiRead<T1, T2, T3>(string sql) { using (var connection = new SqlConnection(conString)) using (var multi = connection.QueryMultiple(sql, null)) { return (multi.Read<T1>().ToList(), multi.Read<T2>().ToList(), multi.Read<T3>().ToList()); } }
这种方式没有反射开销,且编译时就能保证类型安全,但需要提前预设常用的泛型参数数量。
内容的提问来源于stack exchange,提问作者dbsoft
相关产品推荐
相关产品推荐

