android - 如何针对特殊的 "many-to-many relationship"用例查询 Android Room CrossReference 实体中的数据?

标签 android database nested relationship android-room

我按照 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 结构。非常感谢您!

最佳答案

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

    @Relation(
         entity = PlaylistSongCrossRef::class,
         parentColumn = "playlistId"
         entityColumn = "playlistId"
    )
    val baseVolumes: List<PlaylistSongCrossRef>
)

把后面的Relation改成这个,就会得到对应的CrossRef列表。

关于android - 如何针对特殊的 "many-to-many relationship"用例查询 Android Room CrossReference 实体中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64165335/

相关文章:

c - for 循环内有 while 循环是否被视为嵌套 while 循环?

python - 如何从平面列表中制作嵌套列表?

c - 为什么我不能在嵌套结构中初始化数组?

mysql - 在 Sequelize 中使用表变量?

sql-server - Visual Studio 2010 中数据库开发的最佳实践?

java - 如何在 Espresso 的 RecyclerView 中断言?

Android - 在更深层的现有 View 之上精确绘制 ImageView

java - 如何使用 Spotify Web API 的 PUT 命令通过 Android 应用程序暂停我的 Spotify

android - 适用于 Android 4+ 的 Roboto 字体?

mysql - 我可以用 cratedb 替换 mysql 大表吗