Android Room返回Flow的DAO方法仅单次发射组合对象数据问题
问题:Room一对一关联查询的Flow仅发射一次数据
我有Location和Weather两张表,二者为一对一关联关系,Weather表通过外键存储对应Location表的id字段。
Location实体代码:
@Entity(tableName = "location") data class Location( @PrimaryKey(autoGenerate = true) val id: Long = 0, ... )
Weather实体代码:
@Entity( tableName = "weather", foreignKeys = [ ForeignKey( entity = Location::class, parentColumns = ["id"], childColumns = ["locationId"], onDelete = ForeignKey.CASCADE ) ] ) data class Weather( @PrimaryKey(autoGenerate = true) val id: Int = 0, @ColumnInfo(name = "locationId") val locationId: Long, ... )
定义的组合类:
data class LocationWeather( @Embedded val location: Location, @Relation( parentColumn = "id", entityColumn = "locationId" ) val weather: Weather )
我希望返回Flow<List<LocationWeather>>,以便当任意一张表更新时能发射新数据。DAO方法如下:
@Transaction @Query("SELECT * FROM location") fun getLocationWeatherList(): Flow<List<LocationWeather>>
在ViewModel中调用测试:
locationDao.getLocationWeatherList().onEach { // 仅触发一次... }.launchIn(viewModelScope)
但该Flow仅发射一次数据,即使数据库检查器显示Location或Weather表已有新条目,更新后也不会再发射新数据。我遵循了官方文档,唯一区别是DAO方法返回Flow<List<LocationWeather>>而非List<LocationWeather>。请问这是预期行为还是我遗漏了什么?
解决方案
- Room的
@Relation关联查询生成的Flow,默认只会监听主表(即查询语句中的location表)的变化,不会自动监听关联表(weather表)的更新。这就是更新Weather表时Flow不发射新数据的核心原因。 - 要让Flow同时监听两张表的变化,需要在查询语句中显式关联两张表,而不是只查询主表。修改DAO的查询语句:
如果允许@Transaction @Query("SELECT location.* FROM location INNER JOIN weather ON location.id = weather.locationId") fun getLocationWeatherList(): Flow<List<LocationWeather>>Location没有对应Weather的情况,可使用LEFT JOIN:@Transaction @Query("SELECT location.* FROM location LEFT JOIN weather ON location.id = weather.locationId") fun getLocationWeatherList(): Flow<List<LocationWeather>> - 修改后,无论是
Location表还是Weather表的数据发生变化,Flow都会自动发射最新的关联数据列表。
内容的提问来源于stack exchange,提问作者Mehmed
相关产品推荐
相关产品推荐

