首页 > 解决方案 > 如何在 Android Room CrossReference 实体中查询特殊“多对多关系”用例的数据?

问题描述

我按照 android 开发指南定义 Room 多对多关系: https ://developer.android.com/training/data-storage/room/relationships#many-to-many

data class Playlist(
    @PrimaryKey val playlistId: Long,
    val playlistName: String
)

@Entity
data class Song(
    @PrimaryKey val songId: Long,
    val songName: String,
    val artist: String
)

@Entity(primaryKeys = ["playlistId", "songId"])
data class PlaylistSongCrossRef(
    val playlistId: Long,
    val songId: Long
)

data class PlaylistWithSongs(
    @Embedded val playlist: Playlist,
    @Relation(
         parentColumn = "playlistId",
         entityColumn = "songId",
         associateBy = @Junction(PlaylistSongCrossRef::class)
    )
    val songs: List<Song>
)

// Dao
@Transaction
@Query("SELECT * FROM Playlist")
fun getPlaylistsWithSongs(): List<PlaylistWithSongs>

以上工作正常。但是,我还想根据歌曲所属的播放列表保存歌曲的声音属性(即基本音量...)。对于同一首歌曲,在“派对”播放列表中音量高,在“冷静”播放列表中音量低。对于同一个播放列表类似,某些歌曲的音量很高,而其他歌曲的音量较低。

所以我改变了上面的 PlaylistSongCrossRef 并添加了 Dao 如下:

@Entity(table="playlistSongCrossRef", primaryKeys = ["playlistId", "songId"])
data class PlaylistSongCrossRef(
    val playlistId: Long,
    val songId: Long,
    val baseVolume: Double
)

data class PlaylistWithSongs(
    @Embedded val playlist: Playlist,
    @Relation(
         parentColumn = "playlistId",
         entityColumn = "songId",
         associateBy = Junction(PlaylistSongCrossRef::class)
    )
    val songs: List<Song>
    @Relation(
         parentColumn = "playlistId",
         entityColumn = "baseVolume",
         associateBy = Junction(PlaylistSongCrossRef::class)
    )
    val baseVolumes: List<PlaylistSongCrossRef>
)

// Dao
@Query("SELECT * FROM Playlist WHERE playlistId = :playlistId ")
fun getPlaylistsWithSongs(playlistId: Int): List<PlaylistWithSongs>

但是,dao 查询没有按预期工作。当相同的 baseVolume 存储在不同的 song-playlistCrossRef 对中时,查询将返回重复的条目。

我不确定这是 dao 中的错误查询还是我需要重新设计 Room DB 结构。非常感谢您!

标签: androiddatabasenestedrelationshipandroid-room

解决方案


推荐阅读