如何将Map<String,List<dynamic>>转为Map<String,List<DetailedPositions>>?解决类型异常
PostgreSQL查询结果分组转自定义对象集合报错解决方案
问题概述
从PostgreSQL读取记录并按cust_id层级分组,尝试将Map<String, List<dynamic>>转换为Map<String, List<DetailedPositions>>时,抛出异常:'_PostgreSQLResultRow' is not a subtype of type 'Map<String, dynamic>'。
错误原因
_fetchMasterPositionData!.toList()返回的是List<_PostgreSQLResultRow>类型集合,而非List<Map<String, dynamic>>。直接将_PostgreSQLResultRow实例传入DetailedPositions.fromJson()会报错,因为该工厂方法要求参数为Map<String, dynamic>类型。
解决方案
方案1:直接从ResultRow构造对象(推荐)
跳过fromJson方法,直接从_PostgreSQLResultRow中提取字段值构造DetailedPositions实例,避免Map转换步骤:
核心修正代码:
groupedPositions.forEach((key, value) { newMap[key] = value.map((e) => DetailedPositions( custID: e[0].toString(), custName: e[1].toString(), quantity: e[2] as int, )).toList(); });
方案2:将ResultRow转为Map后适配fromJson
如果必须使用fromJson方法,需先将_PostgreSQLResultRow转为对应的Map<String, dynamic>,注意数据库字段名与fromJson中key的对应关系:
groupedPositions.forEach((key, value) { newMap[key] = value.map((e) => DetailedPositions.fromJson({ 'custID': e[0], 'custName': e[1], 'quantity': e[2], })).toList(); });
若使用的postgres库支持ResultRow.toColumnMap()方法(返回字段名到值的映射),可调整fromJson适配数据库字段名后直接转换:
// 修改DetailedPositions.fromJson适配数据库字段名 factory DetailedPositions.fromJson(Map<String, dynamic> json) { return DetailedPositions( custID: json['cust_id'] as String, custName: json['cust_name'] as String, quantity: json['net_quantity'] as int, ); } // 转换逻辑 groupedPositions.forEach((key, value) { newMap[key] = value.map((e) => DetailedPositions.fromJson(e.toColumnMap())).toList(); });
完整修正后代码
Future<Map<String, List<DetailedPositions>>> fetchDetailedPositions( String custID) async { await connection!.open(); Map<String, List<DetailedPositions>> newMap = {}; await connection!.transaction((fetchDataConn) async { final _fetchMasterPositionData = await fetchDataConn.query( "SELECT cust_id, cust_name, net_quantity FROM positions"); if (_fetchMasterPositionData.affectedRowCount > 0) { final fetchDataFuture = _fetchMasterPositionData.toList(growable: true); final Map<String, List<dynamic>> groupedPositions = groupBy( fetchDataFuture, (item) => item[0].toString() + ',' + item[1]); groupedPositions.forEach((key, value) { newMap[key] = value.map((e) => DetailedPositions( custID: e[0].toString(), custName: e[1].toString(), quantity: e[2] as int, )).toList(); }); } }); return newMap; } class DetailedPositions { String custID; String custName; int quantity; DetailedPositions({ required this.custID, required this.custName, required this.quantity, }); // 若使用方案2,可保留或修改此方法 factory DetailedPositions.fromJson(Map<String, dynamic> json) { return DetailedPositions( custID: json['custID'] as String, custName: json['custName'] as String, quantity: json['quantity'] as int, ); } }
内容的提问来源于stack exchange,提问作者anilraj
相关产品推荐
相关产品推荐

