Flutter集成Moor数据库await查询结果时报Null check operator错误求助
问题根因与修复方案
错误栈明确指向生成的database.g.dart中$TasksTable.map方法里的空值断言!触发异常:从数据库查询返回的行数据中存在null字段,但生成的代码默认你定义的字段都是非空类型,强制解包null直接抛出崩溃。
常见触发原因及修复
原因1:表结构变更后未升级数据库版本、补充迁移逻辑
你在Tasks表中新增isHighPriority字段后,没有修改schemaVersion也没有写迁移逻辑,设备上残留的旧版本数据库的tasks表不存在is_high_priority列,查询时该字段返回null,触发空断言崩溃。
修复步骤:
- 升级schema版本,补充迁移逻辑:
@UseMoor(tables: [Tasks]) class Database extends _$Database { Database() : super(FlutterQueryExecutor.inDatabaseFolder( path: 'db.sqlite', logStatements: true)); // 版本从1升级为2 @override int get schemaVersion => 2; // 新增迁移逻辑 @override MigrationStrategy get migration => MigrationStrategy( onUpgrade: (m, from, to) async { if (from == 1) { // 给旧表新增is_high_priority字段,默认值为0对应false await m.addColumn(tasks, tasks.isHighPriority); } }, ); Future<List<Task>> getAllTasks() => select(tasks).get(); Future insertTask(Task task) => into(tasks).insert(task); Future deleteTask(Task task) => delete(tasks).delete(task); }
- 重新执行代码生成命令:
flutter packages pub run build_runner build
开发阶段也可以直接卸载设备上的App重装,清空旧数据库即可快速验证问题。
原因2:字段非空约束与实际数据不符(较少见)
如果业务上允许isHighPriority字段为空,可以修改表定义,给字段添加可空标记:
@UseRowClass(Task) class Tasks extends Table { TextColumn get id => text()(); TextColumn get title => text()(); // 加nullable()标记允许字段为空 BoolColumn get isHighPriority => boolean().nullable()(); Set<Column> get primaryKey => {id}; }
同时同步修改Task类中isHighPriority的类型为可空bool?,再重新生成代码即可。
补充优化点
你当前TodoBloc中AddTask事件的逻辑没有等待数据库插入完成就直接返回状态,可能出现数据不一致的问题,建议调整为:
if (event is AddTask) { // 等待插入完成 await _database.insertTask(event.task); // 重新从数据库拉取最新数据,避免状态异常 final tasks = await _database.getAllTasks(); yield TasksUpdated(tasks); }
内容的提问来源于stack exchange,提问作者kforjan
相关产品推荐
相关产品推荐

