【问题标题】:How to properly construct Room Entities with Inheritance如何正确构造具有继承的房间实体
【发布时间】:2019-11-25 18:38:48
【问题描述】:

我有一个我希望每个实体都拥有的字段列表,因此我创建了一个基本实体。

open class Syncable(
    @ColumnInfo(name = "id")
    var oid: String? = null,
    @ColumnInfo(name = "created")
    var created: Long = System.currentTimeMillis(),
    @ColumnInfo(name = "updated")
    var updated: Long = System.currentTimeMillis())

然后我有许多从这个继承的实体,例如:

@Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
data class Profile(ColumnInfo(name = "first_name")
     var firstName: String,
     @ColumnInfo(name = "last_name")
     var lastName: String,          
     @ColumnInfo(name = "email")
     var email: String? = null,
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
     var id: Long? = null) : Syncable()

现在,当我想构建这些实体之一时。我该怎么做?

目前我这样做:

val newProfile = Profile(
                    "Bob",
                    "Shoruncle",
                    "bobshoruncle@test.com)
newProfile.id = "bob1"
newProfile.created = 1233L
newProfile.updated = 1233L

有没有办法做到:

val newProfile = Profile("Bob", "Shoruncle", "bobshoruncle@test.com","bob1",1233L,1233L)

【问题讨论】:

    标签: android inheritance kotlin constructor android-room


    【解决方案1】:

    你不能做这样的事情吗:

    open class Syncable(
        @ColumnInfo(name = "id")
        var oid: String? = null,
        @ColumnInfo(name = "created")
        var created_on: Long = System.currentTimeMillis(),
        @ColumnInfo(name = "updated")
        var updated_on: Long = System.currentTimeMillis())
    
    @Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
    data class Profile(ColumnInfo(name = "first_name")
         var firstName: String,
         @ColumnInfo(name = "last_name")
         var lastName: String,          
         @ColumnInfo(name = "email")
         var email: String? = null,
         @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
         var id: Long? = null) : Syncable(){
        constructor(profile: Account) : this(profile.firstName, profile.lastName, profile.email, profile.id,profile.oid, profile.created_on, profile.updated_on)
    }
    

    基本上,尝试查看调用 kotlin 的超级方法构造函数

    我试图在这里根据这篇文章来回答我的问题,看看,希望对你有帮助:Call super class constructor in Kotlin, Super is not an expression

    【讨论】:

    • 我试过了,但唯一有效的构造函数参数不包括 Syncable 中的字段。
    【解决方案2】:

    @a_local_nobody 是在正确的轨道上,但答案更复杂。

    我需要在子类上创建一个自定义构造函数来设置父类的字段

     @Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
     data class Profile(ColumnInfo(name = "first_name")
     var firstName: String,
     @ColumnInfo(name = "last_name")
     var lastName: String,          
     @ColumnInfo(name = "email")
     var email: String? = null,
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
     var id: Long? = null) : Syncable() {
     @Ignore constructor(
       firstName: String,
       lastName: String,
       email: String,
       id: String,
       created: Long,
       updated:Long) : this(firstName, lastName, email) {
         this.id = id
         this.created = created
         this.updated = updated
       }
     }
    

    现在对于外部创作者来说,它看起来像是一个大型构造函数

    【讨论】:

    • 出于好奇,更新与使用@Embedded相比如何?
    • 通过继承,您可以像在子对象中一样更新字段,使用简单的点表示法,您不需要先构造内部对象。 @Embedded 将对象折叠到 db 表中,但它仍然存在于数据对象中,因为它是自己的内部类。
    • 该死,这就是我想要实现的目标:P 我会支持你的答案,找到它做得很好,很高兴我能帮上忙 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多