【问题标题】:Save transient field in Room Database在房间数据库中保存瞬态字段
【发布时间】:2021-08-05 04:30:39
【问题描述】:

考虑以下数据模型,其中 status 由 API 在顶层提供,message 在嵌套级别提供(实际上并非如此,只是为了说明问题):

data class (
    @Json(name = "status")
    val status: Int,

    @Transient
    val message: String
)

现在,假设我想将此数据模型保存到我的数据库中。我会像这样更改模型:

data class (
    @ColumnInfo(name = "status")
    @Json(name = "status")
    val status: Int,

    @ColumnInfo(name = "message")
    @Transient
    val message: String
)

由于Transient 注释,message 字段将不会保存到数据库中。但如果我想怎么办?如何强制 Room 保存字段但 Moshi 忽略它。

问题是我无法控制这个 API,或者它将来会如何变化,所以删除 @Transient 并将名称更改为一些随机复杂的字符串并不是一个理想的解决方案,即使它会解决问题.


Moshi上发现了几个相关问题:

显然这是一个古老的问题......

【问题讨论】:

    标签: android kotlin android-room moshi


    【解决方案1】:

    也许,您可以在对象和 Room 数据库之间使用映射器吗?

    喜欢:

    data class MessageEntity(
        @ColumnInfo(name = "status")
        val status: Int,
        @ColumnInfo(name = "message")
        val message: String
    ) {
    // ... 
    }
    
    data class Message (
        @Json(name = "status")
        val status: Int,
    
        @Transient
        val message: String
    ) {
     fun toEntity(): MessageEntity {// ...}
     fun fromEntity(e: MessageEntity): Message {// ...} // or Extensions
    }
    

    【讨论】:

    • 谢谢!是的,我确实考虑过这一点,但我很犹豫要不要这样做,你看我已经有大约 200-300 个数据类,我必须在其中大约 34 个中这样做。因此,我正在寻找一种所需更改最少的解决方案。不仅如此,这些数据类已经集成到代码中,我也必须重构它们。真是一场噩梦! :-)
    • 另一种可能,您可以使用Moshi custom adapter。你已经试过了吗?它可能更“干净”。
    • message 存在的原因一个自定义适配器,它读取嵌套数据块并将其移动到顶部。但这就是您看到的问题,类型适配器在实体级别创建了一个字段,因此通过强制我使用 Transient 注释来安全地从 API 响应解析中排除。我想在 OP 中解释这一点和上述内容,但这夸大了问题本身,所以我最终删除了所有有利于简洁的内容并保持问题不具体(叹气)。也许我应该保留它!
    • 我明白你的意思,是的,你最初的答案是它应该如何实施,但就像我说的那样,它有点影响力。我可能最终会这样做,在这种情况下我会接受你的回答,但我宁愿不要很快采用最终解决方案,也不会不努力寻找不同/更简单的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2021-01-22
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多