Flutter加载本地数据库数据时String无法转DateTime异常如何解决
问题根因
你使用的本地NoSQL数据库(如sembast)本身不支持直接存储DateTime类型,写入数据时你已将DateTime转换为字符串(通常为ISO 8601格式)存储,读取时直接用as DateTime强转字符串类型的存储值,就会触发类型不匹配异常。
修复步骤
- 修正数据库读取时的日期字段解析逻辑
将抛出异常的行替换为字符串转DateTime的逻辑,修改后的代码如下:
- 修正数据库读取时的日期字段解析逻辑
date: DateTime.parse(record['date'] as String),
如果你写入时存的是毫秒级时间戳,可替换为DateTime.fromMillisecondsSinceEpoch(record['date'] as int)即可。
- 优化方法返回类型,提升类型安全性
你提问中提到的List transactionList = <Transactions>[];写法不是拷贝构造函数,只是声明了一个元素类型为Transactions的空列表。建议将loaddata方法的返回值从List<dynamic>改为明确的List<Transactions>,修改如下:
- 优化方法返回类型,提升类型安全性
// 修改方法返回值类型 Future<List<Transactions>> loaddata() async { var db = await opendb(); var store = intMapStoreFactory.store('expense'); var snapshot = await store.find(db); // 简化列表声明 final transactionList = <Transactions>[]; for (var record in snapshot) { transactionList.add(Transactions( title: record['title'] as String, subtitle: record['subtitle'] as String, date: DateTime.parse(record['date'] as String))); } return transactionList; }
修改后返回的列表可以直接用于页面渲染,无需额外类型转换。
- 同步修改Provider中的变量类型
将TransactionProvider中的transactions变量类型从List<dynamic>改为List<Transactions>,避免后续使用时出现类型问题:
- 同步修改Provider中的变量类型
class TransactionProvider with ChangeNotifier { // 修改为明确类型 List<Transactions> transactions = []; void addTransaction(Transactions statement) async { var db = TransactionDB(dbName: 'transactions.db'); transactions = await db.loaddata(); notifyListeners(); } }
补充注意
写入数据到数据库时,要保证和读取逻辑对应,需将DateTime转为ISO 8601字符串存储,示例如下:
await store.add(db, { 'title': transaction.title, 'subtitle': transaction.subtitle, 'date': transaction.date.toIso8601String(), });
内容的提问来源于stack exchange,提问作者warag
相关产品推荐
相关产品推荐

