通过DAO方法返回Map对象

4
我希望我的dao对象中有这样的方法。
@Query("SELECT c.name, sum(p.value) FROM payments p, paymentCategories c WHERE p.categoryId = c.id GROUP BY c.name")
fun getCategoryStats(): Map<String, Float>

但我遇到了错误

错误: 不确定如何将Cursor转换为此方法的返回类型       public abstract java.util.Map

有可能将其更改为可工作版本吗?

因此,返回类型可以是不同的,但主要条件是

  1. 数据库中必须仅有一个查询
  2. 我想避免编写额外代码,例如仅针对此方法创建附加数据结构

你可能可以创建一个从CursorMapTypeConverter,并在你的DAO上注册它,尽管我没有尝试过这个特定的场景(转换DAO方法的返回值)。但错误消息表明TypeConverter可以在这里使用。 - CommonsWare
很遗憾,这方面没有内置支持。也许当您聚合数据以获取所需信息时,这并不是罕见的情况。无论如何,还是谢谢。 - Ilia Vladimirskiy
我无论如何都无法使用Cursor to Map/Pair转换器。可能是不支持,或者我错过了一个简单的点。作为解决方案,我创建了自己的Tuple对象,并返回其列表。 - guness
2个回答

7

我来晚了, 但或许仍有人需要这个信息。

从2.4版本开始,我们可以使用多重映射的返回类型,并且通过注释@MapInfo定义键和值之间的映射关系。

在您的情况下,应该像这样:

@MapInfo(keyColumn = "name", valueColumn = "sum")    
@Query("SELECT c.name AS name, sum(p.value) AS sum FROM payments p, paymentCategories c WHERE p.categoryId = c.id GROUP BY c.name")
fun getCategoryStats(): Map<String, Float>

更多信息: https://developer.android.com/training/data-storage/room/accessing-data#multimap 请问有其他需要翻译的内容吗?

1
成功了!非常感谢!我甚至没有想到房间可以做到这一点。 - Pavel Shorokhov

0

虽然我认为这不能在Dao中完成,但可以在存储库或viewModel中查询LiveData时使用转换轻松完成(或者您正在查询列表的任何地方)。由于我不知道您的数据名称,因此我使用了虚构的名称:

val categoryStatsMap: LiveData<Map<String, Float>> = 
    Transformations.map(
        database.categoryStatsDao.getCategoryStats()) {it ->
            it.map {it.key to it.value}.toMap()
}

'

it.key'和'it.value'是实体对象中要用作映射键值对的字段。转换可以基于另一个实时数据对象为您提供实时数据对象。我不知道开销是多少,但我认为它不应该太大。

'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接