问题描述
考虑一些存储在Room数据库中的通用@Entity User
。某些@Dao
重新运行LiveData<List<User>>
又名'dao结果'。我希望创建另一个 live 列表,其中每个元素都是dao结果的转换,例如
LiveData<List<UserWrapper>>
//UserWrapper needs a User to construct
所以我写类似
Transformations.map(daoResult,list -> {
List<UserWrapper> newList=new ArrayList<>(list.size());
list.forEach(user -> {
newList.add(new UserWrapper(user));
});
return newList;
});
如果我对LiveData的理解是正确的,则dao结果仅响应List
级别的更改,例如,将列表添加到列表中,从列表中减去等,如果底层User对象是或其字段更改,则不行。
- 这正确吗?
说在数据库中进行了一些更改,这些更改使一些新记录符合基础dao结果的@Query
在上述实现中,每次修改底层的 list 时,地图都会创建一个新的List并将其重新初始化,这在我看来似乎是效率低下并且是某种错误。为什么必须手动检查两个列表以确保有效的转换状态?
- 是否有更好的方法可以使
User
和UserWrapper
之间始终保持1-1对应?
解决方法
我不确定我是否明白你的问题,但请考虑一下我的想法:
- 使用LiveData作为查询的返回类型时,Room为您设置了某种回调。因此,如果您在查询中使用
select * from users ...
,则对表users
的每次更改都会触发更新LiveData的值(这并不明显,所以我的意思是-即使某些用户已被更改,但EACH仍在更改中您的结果列表)。 - 理论上,您不仅可以从查询到表
user
,还可以到表List<User>
。它取决于List<UserWrapper>
和UserWrapper
结构。为此,您应该使用与User
字段匹配的字段或使用Room's Relations来编写查询。