具有相同名称的键的 Kotmin Room crossRef 实体

Kotmin Room crossRef Entity with keys having the same name

我正在创建一个 CRUD 工厂。基本上,我所有的实体都将从以 id 作为主键的 BaseEntity 继承 我试图了解如何为 M2M 关系创建交叉引用 table。 这是一个没有继承的简化示例。 ArticlesEntity 有很多 MagasinsEntityMagasinsEntity 很多 ArticlesEntity。实体 ArticlesMagasinsCrossRef 是结点

但是 ArticlesEntity 和 MagasinsEntity 都有 id 作为主键。

@Entity(
    tableName = "articles"
)
data class ArticlesEntity(
    @PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
    val title: String,
)

@Entity(tableName = "magasins")
data class MagasinsEntity(
    @PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
    val nomMagasin: String

)

@Entity(
    tableName = "articles_magasins"
   )

data class ArticlesMagasinsCrossRefEntity(
    val id: UUID, // how is it possible here to have the id of Articles ?
    val id: UUID // how is it possible here to have the id of Magasins ?
)

编辑 我当然尝试更改列的名称:

data class ArticlesMagasinsCrossRefEntity(
            val articleRd: UUID
            val magasinId: UUID 
        )

但是关系数据构建失败class:例如

data class RelMagasinWithArticles(

    @Embedded val magasin: MagasinsEntity,
    @Relation(
        parentColumn = "magasinId",
        entityColumn = "id",
        associateBy = Junction(ArticlesMagasinsCrossRefEntity::class)
    )
    val articles: List<ArticleEntity>

)

您需要使用 JunctionparentColumnentityColumn 参数,例如

data class RelMagasinWithArticles(

    @Embedded val magasin: MagasinsEntity,
    @Relation(
        parentColumn = "id", /* The column in the @Embedded table (articles) */
        entityColumn = "id", /* The column in the Related table (magasins) */
        associateBy = Junction(
            ArticlesMagasinsCrossRefEntity::class,
            parentColumn = "magasinId", /* The column in the junction table that maps to the @Embedded table */
            entityColumn = "articleRd" /* The column in the junction table that maps to the @Relation Table */
        )
    )
    val articles: List<ArticlesEntity>
)

备注

您还需要为 ArticlesMagasinsCrossRefEntity class 定义一个主键,例如:-

@Entity(
    tableName = "articles_magasins",
    /*<<<<< all Room table MUST have a primary key */
    /* as primary key on a single column would be restrictive use a composite
        primary key
     */
    primaryKeys = ["articleRd","magasinId"] 
)

data class ArticlesMagasinsCrossRefEntity(

    /* Cannot have identical member names - i.e. only 1 could be id
    val id: UUID, // how is it possible here to have the id of Articles ?
    val id: UUID // how is it possible here to have the id of Magasins ?
     */
    val articleRd: UUID,
    /* Room will issue warning if the is no index on the 2nd column */
    @ColumnInfo(index = true)
    val magasinId: UUID
)
  • 请注意,您可以使用@ColumnInfo 名称参数来指定列名称。

演示

所以使用你的代码,建议的代码覆盖你的代码,并使用以下@Dao 接口:-

@Dao
interface AllDao {

    @Insert
    fun insert(articlesEntity: ArticlesEntity)
    @Insert
    fun insert(magasinsEntity: MagasinsEntity)
    @Insert
    fun insert(articlesMagasinsCrossRefEntity: ArticlesMagasinsCrossRefEntity)

    @Query("SELECT * FROM magasins")
    @Transaction
    fun getMWA(): List<RelMagasinWithArticles>
}

一个合适的@Database注解class和代码在activity:-

lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    db = TheDatabase.getInstance(this)
    dao = db.getAllDao()

    val a1uuid = UUID.randomUUID()
    val a2uuid = UUID.randomUUID()
    val a3uuid = UUID.randomUUID()
    dao.insert(ArticlesEntity(a1uuid, "Article1"))
    dao.insert(ArticlesEntity(a2uuid,"Article2"))
    dao.insert(ArticlesEntity(a3uuid,"Article3"))

    val m1uuid = UUID.randomUUID()
    val m2uuid = UUID.randomUUID()
    val m3uuid = UUID.randomUUID()
    dao.insert(MagasinsEntity(m1uuid,"Magasin1"))
    dao.insert(MagasinsEntity(m2uuid,"Magasin2"))
    dao.insert(MagasinsEntity(m3uuid,"Magasin3"))

    dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m2uuid))
    dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m3uuid))

    dao.insert(ArticlesMagasinsCrossRefEntity(a2uuid,m1uuid))

    dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m1uuid))
    dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m2uuid))
    dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m3uuid))

    val sb = StringBuilder()
    for(mwa in dao.getMWA()) {
        sb.append("\nMagasin is ${mwa.magasin.nomMagasin}. ID is ${mwa.magasin.id} it has ${mwa.articles.size} articles. They are:-" )
        for (article in mwa.articles) {
            sb.append("\n\tArticle is ${article.title} ID is ${article.id}")
        }
    }
    Log.d("DBINFO",sb.toString())
}

日志的输出是:-

D/DBINFO: Magasin is Magasin1. ID is 0f3384ee-6232-423e-b2f1-a12ebdac6487 it has 2 articles. They are:-
        Article is Article2 ID is 2729d017-de05-41d2-8de3-8351dfca0a6b
        Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
    Magasin is Magasin2. ID is ba649833-a8ce-4cf2-a1b8-bcab8f7a7d0a it has 2 articles. They are:-
        Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
        Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
    Magasin is Magasin3. ID is eed6f0a5-0825-4cda-9eb4-c4e973a49738 it has 2 articles. They are:-
        Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
        Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19