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

如何用Kotlin Flow手动映射Room一对一关系且无需创建额外组合类

解决方案

方案1:使用挂起版CategoryDao(推荐,性能更优,适合分类变动少的场景)

你之前的问题核心有两点:

  1. 返回Flow的方法不需要加suspend修饰,Flow是冷流,只有收集时才会执行逻辑,挂起修饰属于多余声明
  2. 自定义的mapIterable扩展没有支持挂起函数转换
    修改步骤:
  3. 保留挂起版的CategoryDao定义:
@Dao
interface CategoryDao {
    @Query("SELECT * FROM categories WHERE uid = :id")
    suspend fun get(id: Int): DatabaseCategory
}
  1. 修改mapIterable扩展,支持挂起转换逻辑:
inline fun <T, R> Flow<Iterable<T>>.mapIterable(crossinline transform: suspend (T) -> R): Flow<List<R>> =
    map { iterable ->
        iterable.map { item -> transform(item) }
    }
  1. 去掉Repository中getAll方法的suspend修饰:
override fun getAll(): Flow<List<Transaction>> {
    return transactionDao
        .getAll()
        .mapIterable{ tx ->
            Transaction(tx, categoryDao.get(tx.categoryId))
        }
}

方案2:保留CategoryDao的Flow返回值(适合分类需要实时同步更新的场景)

如果需要分类修改时自动同步更新关联的交易列表,可以直接组合多个Flow实现关联,不需要修改Dao为挂起函数:

override fun getAll(): Flow<List<Transaction>> {
    return transactionDao.getAll()
        .flatMapConcat { transactions ->
            // 为每个交易生成对应的分类Flow,再组合所有Flow为列表
            transactions.map { tx ->
                categoryDao.get(tx.categoryId)
                    .map { category -> Transaction(tx, category) }
            }.combine { transactionList -> transactionList.toList() }
        }
}

两种方案都不需要额外创建TransactionAndCategory关联类,完全符合你的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:30:02