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

Drift(Moor)中实现学生与分组表一对多关联的方法

一对多关联实现方案

第一步:修正表结构,添加外键关联

你当前代码存在两处需要调整的点:

  • GroupDB作为主表,主键id不应该设置为可空,去掉nullable()声明
  • StudentsDB从表需要新增groupId外键字段关联GroupDB的主键,同时你当前重复定义了id字段(TableWithIntId已经默认提供自增主键id,无需重复声明)

修改后的表结构代码如下:

class GroupDB extends Table {
  // 主键自增,插入时自动生成,无需手动传值
  IntColumn get id => integer().autoIncrement()();
  TextColumn get groupName => text().named('group_name')();
}

class StudentsDB extends TableWithIntId {
  // 移除重复的id字段定义,TableWithIntId已内置
  TextColumn get firstName => text().named('first_name')();
  TextColumn get lastName => text().named('last_name')();
  // 新增外键关联分组表id,需要级联删除可添加onDelete: KeyAction.cascade参数
  IntColumn get groupId => integer().named('group_id').references(GroupDB, #id)();
}

第二步:更新数据模型

Student模型需要新增groupId字段存储关联的分组id,修改后代码:

class Group {
  Group({
    this.id,
    required this.groupName,
  });
  int? id;
  String groupName;
}

class Student {
  Student({
    this.id,
    required this.firstName,
    required this.lastName,
    required this.groupId,
  });
  int? id;
  String firstName;
  String lastName;
  int groupId;
}

第三步:实现核心业务查询方法

在你的数据库操作类中添加以下方法,即可满足两个核心需求:

  • 获取全部分组列表,用于新增学生时选择分组
  • 根据分组id查询关联的所有学生,用于点击分组时展示列表
  • 新增学生记录的入库方法
// 1. 查询全部分组列表
Future<List<Group>> getAllGroups() async {
  final groupRecords = await select(groupDB).get();
  return groupRecords.map((e) => Group(
    id: e.id,
    groupName: e.groupName
  )).toList();
}

// 2. 根据分组id查询旗下所有学生
Future<List<Student>> getStudentsByGroup(int targetGroupId) async {
  final studentQuery = select(studentsDB)
    ..where((tbl) => tbl.groupId.equals(targetGroupId));
  final studentRecords = await studentQuery.get();
  return studentRecords.map((e) => Student(
    id: e.id,
    firstName: e.firstName,
    lastName: e.lastName,
    groupId: e.groupId
  )).toList();
}

// 3. 新增学生记录
Future<int> createStudent(Student student) async {
  return into(studentsDB).insert(StudentsDBCompanion.insert(
    firstName: student.firstName,
    lastName: student.lastName,
    groupId: Value(student.groupId)
  ));
}

说明:如果需要在删除分组时同步处理关联学生数据,可以在定义外键时配置onDelete规则:

  • KeyAction.cascade:删除分组时自动删除旗下所有学生
  • KeyAction.setNull:删除分组时将对应学生的groupId置空(需要将groupId字段设为可空)

内容的提问来源于stack exchange,提问作者userName

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 12:48:16