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

如何在Flutter Drift中查询多对多关系的指定账户及关联标签?

解决Flutter Moor/Drift多对多关系下按ID获取账户及关联标签的问题

原代码问题分析

  1. 缺少账户表关联:查询从accountsTags中间表启动,但未关联accounts表,导致无法读取账户实体数据。
  2. 错误的查询结果获取方式:getSingleOrNull()仅能返回单条关联记录,无法覆盖一个账户对应多个标签的场景。
  3. 单条结果无法转换为标签列表:单条查询行只能读取单个TagDTO,无法直接得到所需的List<TagDTO>。

优化后的实现方案

方案一:单次关联查询(推荐)

通过一次关联查询获取所有相关数据,再将结果组装为AccountWithTags:

Future<AccountWithTags?> getAccountWithTagsById(int idAccount) async {
  // 关联账户表、中间表、标签表,查询目标账户的所有关联数据
  final rows = await (select(accounts)
        ..where((tbl) => tbl.id.equals(idAccount)))
      .join([
    leftOuterJoin(accountsTags, accountsTags.accountId.equalsExp(accounts.id)),
    leftOuterJoin(tags, tags.id.equalsExp(accountsTags.tagId)),
  ]).get();

  if (rows.isEmpty) return null;

  // 提取账户信息(所有行的账户数据一致,取第一行即可)
  final account = rows.first.readTable(accounts);
  
  // 收集所有非空的标签数据,过滤掉无标签的情况
  final tagsList = rows
      .map((row) => row.readTable(tags))
      .where((tag) => tag != null)
      .cast<TagDTO>()
      .toList();

  return AccountWithTags(account, tagsList);
}

方案二:两次拆分查询(更直观)

先查询账户,再单独查询该账户关联的所有标签:

Future<AccountWithTags?> getAccountWithTagsById(int idAccount) async {
  // 第一步:获取目标账户
  final account = await (select(accounts)..where((tbl) => tbl.id.equals(idAccount))).getSingleOrNull();
  if (account == null) return null;

  // 第二步:查询该账户关联的所有标签
  final tags = await (select(tags)
        ..where((tbl) => exists(
              select(accountsTags)
                ..where((at) => at.accountId.equals(idAccount) & at.tagId.equalsExp(tbl.id)),
            )))
      .get();

  return AccountWithTags(account, tags);
}

中间表优化建议

为避免同一个账户与标签重复关联,建议给中间表添加唯一约束:

@DataClassName("AccountTagDTO")
class AccountsTags extends Table
{
  IntColumn get id => integer().autoIncrement()();
  IntColumn get accountId => integer().references(Accounts, #id)();
  IntColumn get tagId => integer().references(Tags, #id)();

  // 设置复合主键,确保(accountId, tagId)组合唯一
  @override
  Set<Column> get primaryKey => {accountId, tagId};
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:55:09