簡體   English   中英

無法在 Room 數據庫中建立關系

[英]Cannot build relations in Room database

我的 Room 數據庫有問題。 它由 2 個表“cast”、“movie”和一對一關系“movie_cast”組成。 當我嘗試構建項目時,會出現以下錯誤:

error: Entities cannot have relations. 
public final class MovieWithCastDbModel {

error: An entity must have at least 1 field annotated with @PrimaryKey
public final class MovieWithCastDbModel {

當我從 MovieWithCastDbModel class 中刪除 @Entity 注釋時,我得到以下信息

error: Entity class must be annotated with @Entity
public final class MovieWithCastDbModel {

所以無論我做什么,它都會告訴我做相反的事情。

以下是數據類本身:

@Entity(tableName = "cast")
data class CastDbModel(
    @PrimaryKey(autoGenerate = false)
    var id : Int,
    var name: String,
    var profile_path: String,
    var character: String)


@Entity(tableName = "movie")
@TypeConverters(IntConverter::class)
data class MovieDbModel(
    var page: Int,
    @PrimaryKey(autoGenerate = false)
    var id: Int,
    var poster_path: String,
    var overview: String,
    var title: String,
    @ColumnInfo(name = "genre_ids")
    var genre_ids: Genres,
    var runtime: Int)


@Entity(tableName = "movie_cast")
class MovieWithCastDbModel(
    @Embedded
    var movie: MovieDbModel,
    @Relation(
        entity = CastDbModel::class,
        parentColumn = "id",
        entityColumn = "id"
    )
    var cast : CastDbModel
)


data class Genres(
    @Embedded
    var genre_ids: Int

)


class IntConverter {
    @TypeConverter
    fun fromGenres(value: Genres): String {
        return Gson().toJson(value)
    }
    @TypeConverter
    fun toGenres(value: String): Genres {
        return Gson().fromJson(value,Genres::class.java)
    }
}

可能是什么問題?

正如錯誤消息所說。 實體不能有@Relation 注解。

關系實際上並未在表中定義(@Entity 注釋類),它們是獨立的,除非您通過使用外鍵約束來強制引用完整性(即子級必須有父級)另有說明。

相反,如果要使用關系,則創建一個 POJO class 可以組合相關表的數據。

你所擁有的是一個演員表和一個電影表。 MovieCast 表似乎是所謂的關聯表(映射表、引用表和其他名稱)。 它迎合了多對多的關系。 也就是說,一部電影可以有許多相關的演員表,而一個演員表可以與許多電影相關。

所以對於 MovieWithCastDbModel 你想要這樣的東西: -

@Entity(
    tableName = "movie_cast",
    primaryKeys = ["movieIdMap","castIdMap"],
    /* Optional Foreign Key constraints */
    foreignKeys = [
        /* A MovieId MUST be a value of an existing id column in the movie table */
        ForeignKey(
            entity = MovieDbModel::class,
            parentColumns = ["id"],
            childColumns = ["movieIdMap"],
            /* Optional (helps maintain referential integrity) */
            /* if parent is deleted then children rows of that parent are deleted */ 
            onDelete = ForeignKey.CASCADE,
            /* if parent column is changed then the column that references the parent is changed to the same value */
            onUpdate = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CastDbModel::class,
            parentColumns = ["id"],
            childColumns = ["castIdMap"],
            onDelete = ForeignKey.CASCADE,
            onUpdate = ForeignKey.CASCADE
        )
    ]
)
data class MovieWithCastDbModel(
    var movieIdMap: Int,
    @ColumnInfo(index = true)
    var castIdMap: Int
)
  • 將其稱為 MovieCast 或 MoviesCastMap 可能比 MovieWithCast 更好。

現在,為了允許提取 MoviesWithCast,您將擁有一個使用 @Embedded 的 MovieDbModel 和一個定義關聯表的 @Relation 的 POJO。

所以像: -

data class MovieWithListOfCast(
    @Embedded /* The parent */
    var movie: MovieDbModel,
    @Relation(
        entity = CastDbModel::class, /* The class of the related table(entity) (the children)*/
        parentColumn = "id", /* The column in the @Embedded class (parent) that is referenced/mapped to */
        entityColumn = "id", /* The column in the @Relation class (child) that is referenced (many-many) or references the parent (one(parent)-many(children)) */
        /* For the mapping table */
        associateBy = Junction(
            value = MovieWithCastDbModel::class, /* The class of the mapping table */
            parentColumn = "movieIdMap", /* the column in the mapping table that maps/references the parent (@Embedded) */
            entityColumn = "castIdMap" /* the column in the mapping table that maps/references the child (@Relation) */
        )
    )
    var castList: List<CastDbModel>
)

如果您在 @Dao 帶注釋的接口/抽象 class 中有一個 function ,例如

@Transaction
@Query("SELECT * FROM movie")
fun getAllMoviesWithCastList(): List<MovieWithListOfCast>

它將檢索具有相關演員表的所有電影,作為 MovieWithListOfCast 對象的列表(每部電影一個)。

Room 使用 MovieWithListOfCast 中的注釋來提取所有相關演員表。 它通過為每部電影運行的底層查詢來做到這一點,因此為什么應該使用@transaction。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM