You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter集成Moor数据库await查询结果时报Null check operator错误求助

问题根因与修复方案

错误栈明确指向生成的database.g.dart中$TasksTable.map方法里的空值断言!触发异常:从数据库查询返回的行数据中存在null字段,但生成的代码默认你定义的字段都是非空类型,强制解包null直接抛出崩溃。

常见触发原因及修复

原因1:表结构变更后未升级数据库版本、补充迁移逻辑

你在Tasks表中新增isHighPriority字段后,没有修改schemaVersion也没有写迁移逻辑,设备上残留的旧版本数据库的tasks表不存在is_high_priority列,查询时该字段返回null,触发空断言崩溃。

修复步骤:

  1. 升级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);
}
  1. 重新执行代码生成命令:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 11:45:04