Comment modéliser une relation plusieurs-à-plusieurs comme décrit dans https://developer.android.com/training/data-storage/room/relationships#many-to-many , mais avec une propriété supplémentaire sur la jonction? Je souhaite essentiellement réaliser ce qui suit:
/-- A ---\ /- ACrossB -\ /-- B ---\ | | | | | | | - id |----->| - aId | |------| - id | | - name | | - bId |-----| | -name | | | | - prop | | | \--------/ \-----------/ \--------/
pour pouvoir y accéder dans mon Dao:
@Dao interface SongWithPlaylistsDao { @Query("SELECT * FROM Song") fun list(): LiveData<List<SongWithPlaylists>> }
Je sais comment, depuis un ERM perspective, vous modéliseriez cette relation comme ceci:
@Entity 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, val rating: Int // <-- the additional property ) data class PlaylistWithRating( val playlist: Playlist, val rating: Int // <-- the additional property ) data class SongWithPlaylists( @Embedded val song: Song, @Relation( parentColumn = "songId", entityColumn = "playlistId", associateBy = @Junction(PlaylistSongCrossRef::class) ) val playlists: List<PlaylistWithRating> )
Je sais aussi comment interroger cette relation en utilisant JOIN
, mais je n'ai pas pu comprendre la documentation comment faire cela dans Room tout en préservant l'intégrité des données.
3 Réponses :
avez-vous essayé ceci:
@Entity classe de données PlaylistSongCrossRef ( val playlistId: Long, val songId: Long,
@PrimaryKey(autoGenerate = true) val rating: Int // <-- the additional property
)
Remarque: je ne sais pas comment déclarer le primaire dans kotlin, je suis développeur java. Mais vous avez l'idée ... La jonction fonctionnera toujours, alors que vous pouvez avoir de nombreuses associations avec la même chanson différenciées par une note unique.
Je pense que vous n'avez pas besoin de créer une nouvelle classe de données PlaylistWithRating
. Parce que vous pouvez définir la propriété supplémentaire rating
sur entity directement. Par exemple,
Si votre note
est pour playlist
, vous pouvez définir cette propriété comme suit.
@Entity data class Playlist( @PrimaryKey val playlistId: Long, val userCreatorId: Long, val playlistName: String, val rating: Int // <-- the additional property ) @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> ) data class SongWithPlaylists( @Embedded val song: Song, @Relation( parentColumn = "songId", entityColumn = "playlistId", associateBy = @Junction(PlaylistSongCrossRef::class) ) val playlists: List<Playlist> )
Si votre note
est pour chanson
, vous pouvez définir cette propriété comme suit.
@Entity data class Song( @PrimaryKey val songId: Long, val songName: String, val artist: String, val rating: Int // <-- the additional property )
Donc, le La relation plusieurs-à-plusieurs
de votre schéma comme vous l'avez mentionné document sera correcte. Vous n'avez pas besoin de prendre en compte une classe de données supplémentaire pour la propriété rating
.
Donc, cela pourrait être comme suit.
@Entity data class Playlist( @PrimaryKey val playlistId: Long, val userCreatorId: Long, val playlistName: String, val rating: Int // <-- the additional property )
J'espère que cela vous sera utile.
tnx pour vos efforts. mais supposons que nous ne pouvons attribuer cet attribut supplémentaire (note dans ce cas) à aucune des entités. J'ai rencontré un problème similaire dont l'attribut supplémentaire est purement pour l'entité associative.
J'ai rencontré le même problème et je l'ai finalement résolu d'une autre manière. Il y a des cas où vous ne pouvez pas attribuer un attribut à un côté de la relation binaire de sorte que l'attribut appartient à la relation elle-même.
@Dao interface SongWithPlaylistsDao { @Query(""" select Song.songId,Song.songName,Song.artist,Playlist.playlistId,Playlist.playlistName,PlaylistSongCrossRef.rating from Song inner join PlaylistSongCrossRef on Song.songId = PlaylistSongCrossRef.songId inner join Playlist on Playlist.playlistId = PlaylistSongCrossRef.playlistId """) fun list(): LiveData<List<SongWithPlaylists>> }
Je veux en savoir plus sur votre propriété supplémentaire
évaluation
pour quoi? Pour une playlist ou pour une chanson?La note est pour la combinaison de la chanson et de la liste de lecture. Une chanson peut avoir différentes notes sur différentes listes de lecture.
avez-vous résolu ce problème? J'ai un problème similaire (j'ai besoin de la propriété supplémentaire pour commander les chansons de la playlist)
Non désolé. Je n'ai pas eu le temps de continuer à chercher dans Android Room.
@Jeremy Mon anglais est médiocre, mais j'ai ouvert un problème dans le suivi des problèmes de Google à l'adresse issuetracker.google.com/issues/ 169467510 J'ai rencontré le même problème et la seule solution de contournement que je pense est d'utiliser Sqlite sale