【问题标题】:Nested embedded lists on RoomRoom 上的嵌套嵌入式列表
【发布时间】:2021-11-24 15:07:48
【问题描述】:

使用房间我试图拥有一个Something 类型的对象,其中包含Stuff 的列表,并且该列表的每个项目都包含另一个Things 列表。

data class rootWrapper(
        @Embeded
        var somethingEntity: SomethingEntity
         @Relation(
            parentColumn = "id",
            entityColumn = "idSomething",
            associatedBy = Junction(SomethingWithStuffEntity::class)
     )
     var listOfStuff: MutableList<StuffWithThingsInsideWrapper>
)

data class StuffWithThingsInsideWrapper(
        @Embeded
        var stuff: stuffEntity
         @Relation(
            parentColumn = "id",
            entityColumn = "idStuff",
            associatedBy = Junction(StuffWithThingsEntity::class)
     )
     var listOfThings: MutableList<ThingsEntity>
)

问题在于,由于 StuffWithThingsInside 没有 ID。我得到一个Cannot find the parent entity column id in com.test.room.entity.StuffWithThingsWapper。我不知道我想要实现的目标是否可能,我找不到任何例子。有什么建议吗?

【问题讨论】:

    标签: android kotlin android-room


    【解决方案1】:

    我不知道我想要实现的目标是否可行,我找不到任何示例。有什么建议吗?

    有可能。不妨考虑以下几点。

    当您associateBy 时,您是在说您正在使用关联表来访问父级和子级。

    这样的表至少有两列,在您的情况下,一列引用 stuffEntity,另一列引用相关 ThingEntity。

    因此,@RelationassociateBy 涉及 4 列:-

    • 父级,即@Embedded
    • The Child(ren) 即@Relation
    • 关联表中引用@Embedded 的列
    • 关联表中引用@Relation 的列

    前两个根据@Relation 的父参数和实体参数,后两个根据'Junction'。

    此外,当包含层次结构/级别时,您遇到的更复杂的情况是,与变量匹配的列需要下属的 实体,而该下属实体不在下属中。您需要将实体类指定为相应的实体,而不是要提取的 POJO 的类。

    所以你可以有类似的东西:-

    data class StuffWithThingsInsideWrapper(
        @Embedded
        var stuff: StuffEntity,
        @Relation(
            entity = ThingsEntity::class,
            parentColumn = "id",
            entityColumn = "id",
            associateBy = (
                    Junction(
                        value = StuffWithThingsEntity::class,
                        parentColumn = "idStuff",
                        entityColumn = "idThings"
                    )
                    )
        )
        var listOfThings: List<ThingsEntity>
    )
    

    和:-

    data class RootWrapper(
        @Embedded
        var somethingEntity: SomethingEntity,
        @Relation(
            entity = StuffEntity::class, //<<<<< The entity behind a Something With Stuff
            parentColumn = "id",
            entityColumn = "id",
            associateBy = (
                    Junction(
                        SomethingWithStuffEntity::class,
                        parentColumn = "idSomething",
                        entityColumn = "idStuff"
                    )
                    )
        )
        var listOfStuff: List<StuffWithThingsInsideWrapper>
    )
    
    • 注意,由于未包含基础实体,因此已猜测列名。

    工作示例/演示

    除了上述之外,还使用了以下类:-

    事情

    @Entity
    data class ThingsEntity(
        @PrimaryKey
        var id: Long? = null,
        var name: String
    )
    

    东西

    @Entity
    data class StuffEntity(
        @PrimaryKey
        var id: Long? = null,
        var name: String
    )
    

    某事

    @Entity
    data class SomethingEntity(
        @PrimaryKey
        var id: Long? = null,
        var name: String
    )
    

    StuffWithThings

    @Entity(
        primaryKeys = ["idStuff","idThings"],
        foreignKeys = [
            ForeignKey(
                entity =  StuffEntity::class,
                parentColumns = ["id"],
                childColumns = ["idStuff"]
            ), ForeignKey(
                entity = ThingsEntity::class,
                parentColumns = ["id"],
                childColumns = ["idThings"]
            )
        ]
    )
    data class StuffWithThingsEntity(
        var idStuff: Long,
        @ColumnInfo(index = true)
        var idThings: Long
    )
    
    • 外键是可选的,它们强制引用完整性

    SomethingWithStuffEntity

    @Entity(
        primaryKeys = ["idSomething","idStuff"],
        foreignKeys = [
            ForeignKey(
                entity = SomethingEntity::class,
                parentColumns = ["id"],
                childColumns = ["idSomething"]
            ), ForeignKey(
                entity =  StuffEntity::class,
                parentColumns = ["id"],
                childColumns = ["idStuff"])
        ]
    )
    data class SomethingWithStuffEntity(
        var idSomething: Long,
        @ColumnInfo(index = true)
        var idStuff: Long
    )
    

    AllDao

    @Dao
    interface AllDao {
        @Insert
        fun insert(thingsEntity: ThingsEntity): Long
        @Insert
        fun insert(stuffEntity: StuffEntity): Long
        @Insert
        fun insert(somethingEntity: SomethingEntity): Long
        @Insert
        fun insert(stuffWithThingsEntity: StuffWithThingsEntity): Long
        @Insert
        fun insert(somethingWithStuffEntity: SomethingWithStuffEntity)
        @Query("SELECT * FROM somethingentity")
        fun getRootWrapperList(): List<RootWrapper>
    
    }
    

    数据库

    @Database(entities = [ThingsEntity::class,StuffEntity::class,SomethingEntity::class,StuffWithThingsEntity::class,SomethingWithStuffEntity::class], version = 1)
    abstract class TheDatabase: RoomDatabase() {
        abstract fun getAllDao(): AllDao
    
        companion object {
            private var instance: TheDatabase? = null
            fun getInstance(context: Context): TheDatabase {
                if (instance == null) {
                    instance = Room.databaseBuilder(
                        context,
                        TheDatabase::class.java,
                        "thedatabase.db"
                    )
                        .allowMainThreadQueries()
                        .build()
                }
                return instance as TheDatabase
            }
        }
    }
    
    • 为了简洁/方便,已使用.allowMainThreadQueries

    最后把它们放在一个活动中:-

    class MainActivity : AppCompatActivity() {
        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 thing1Id = dao.insert(ThingsEntity(name = "Thing1"))
            val thing2Id = dao.insert(ThingsEntity(name = "Thing2"))
            val thing3Id = dao.insert(ThingsEntity(name = "Thing3"))
            val stuff1Id = dao.insert(StuffEntity(name = "Stuff1"))
            val stuff2Id = dao.insert(StuffEntity(name = "Stuff2"))
            val something1Id = dao.insert(SomethingEntity(name = "Something1"))
            val something2Id = dao.insert(SomethingEntity(name = "Something2"))
            val something3Id = dao.insert(SomethingEntity(name = "Something3"))
    
            dao.insert(StuffWithThingsEntity(stuff1Id,thing1Id))
            dao.insert(StuffWithThingsEntity(stuff1Id,thing2Id))
            dao.insert(StuffWithThingsEntity(stuff1Id,thing3Id))
            dao.insert(StuffWithThingsEntity(stuff2Id,thing3Id))
            dao.insert(StuffWithThingsEntity(stuff2Id,thing2Id))
    
            dao.insert(SomethingWithStuffEntity(something1Id,stuff1Id))
            dao.insert(SomethingWithStuffEntity(something1Id,stuff2Id))
            dao.insert(SomethingWithStuffEntity(something2Id,stuff2Id))
    
            for(rw: RootWrapper in dao.getRootWrapperList()) {
                Log.d("RWINFO","Something is ${rw.somethingEntity.name}")
                for (swt: StuffWithThingsInsideWrapper in rw.listOfStuff) {
                    Log.d("RWINFO","\tStuff is ${swt.stuff.name}")
                    for (t: ThingsEntity in swt.listOfThings) {
                        Log.d("RWINFO","\t\tThings is ${t.name}")
                    }
                }
            }
        }
    }
    

    运行上述(第一次)然后输出到日志的结果是:-

    2021-11-25 07:04:58.828 D/RWINFO: Something is Something1
    2021-11-25 07:04:58.828 D/RWINFO:   Stuff is Stuff1
    2021-11-25 07:04:58.828 D/RWINFO:       Things is Thing1
    2021-11-25 07:04:58.828 D/RWINFO:       Things is Thing2
    2021-11-25 07:04:58.828 D/RWINFO:       Things is Thing3
    2021-11-25 07:04:58.828 D/RWINFO:   Stuff is Stuff2
    2021-11-25 07:04:58.828 D/RWINFO:       Things is Thing2
    2021-11-25 07:04:58.828 D/RWINFO:       Things is Thing3
    
    2021-11-25 07:04:58.828 D/RWINFO: Something is Something2
    2021-11-25 07:04:58.828 D/RWINFO:   Stuff is Stuff2
    2021-11-25 07:04:58.829 D/RWINFO:       Things is Thing2
    2021-11-25 07:04:58.829 D/RWINFO:       Things is Thing3
    
    2021-11-25 07:04:58.829 D/RWINFO: Something is Something3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 2018-02-19
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      相关资源
      最近更新 更多