如何在Room中查询复杂的嵌套对象?

时间:2018-01-09 16:14:12

标签: android android-room

我有几个实体可以在下面看到,问题是当你有多个嵌套级别时如何正确选择嵌套列表。如果您查看github上的Google存储库,您可以找到非常简单的示例,但不是复杂的东西。正如文档所说here,Room不允许对象引用。如何获得ResultObject(以及它应该如何看待),包括所有嵌套列表?

ResultObject应具有以下信息:

  1. List<Dialog>
  2. Dialog实体有List<Message>
  3. MessageList<ImageContent>
  4. ImageContentList<ImageContentItem>
  5. 对话框

    @Entity(tableName = "dialog")
    data class Dialog(@PrimaryKey val id String, val title: String)
    

    消息

    @Entity(tableName = "message",
            foreignKeys = [(ForeignKey(entity = Dialog::class, parentColumns ["id"], childColumns = ["dialogId"]))])
    data class Message(@PrimaryKey val id: String, val dialogId: String)
    

    ImageContent

    @Entity(tableName = "image_content",
            foreignKeys = [(ForeignKey(entity = Message::class, parentColumns = ["id"], childColumns = ["messageId"]))])
    data class ImageContent(@PrimaryKey val id: String, val messageId: String)
    

    ImageContentItem

    @Entity(tableName = "image_content_item",
            foreignKeys = [(ForeignKey(entity = ImageContent::class, parentColumns = ["id"], childColumns = ["imageContentId"]))])
    data class ImageContentItem(val imageContentId: String,
                            @PrimaryKey(autoGenerate = true) val id: Long = 1)
    

    DAO:

    @Dao
    interface DialogDao {
        @Query("SELECT * FROM dialog " +
                "INNER JOIN message ON message.dialogId = dialog.id " +
                "INNER JOIN image_content ON image_content.messageId = message.id " +
                "INNER JOIN image_content_item ON image_content_item.imageContentId = image_content.id")
        fun getDialogAllInformation(): Flowable<List<**ResultObject**>>
    }
    

2 个答案:

答案 0 :(得分:15)

您可以根据需要嵌套定义关系的类。

@Relation

我认为Room会员应该有更优雅的东西,因为这个解决方案至少有两个问题。

  1. 它引入了非常烦人的样板。
  2. Dialog注释只能用于列表或集合,因此它不包含您具有1:1关系的场景。
  3. 想象一下,根据定义,您的Message只有一个DeepDialog(而非许多)。在这种情况下,您不希望messages: List<>拥有message: Message访问者,而是class DeepDialog { @Embedded lateinit var embedded: Dialog @Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class) internal lateinit var messages: List<DeepMessage> val message get() = messages.firstOrNull() } 。我发现的唯一方法是:

    letters

答案 1 :(得分:3)

Rooms与entity / table一起使用,它不允许像你需要的那样管理结构化对象。您唯一能做的就是单独执行查询,然后构建ResultObject