【问题标题】:Room insert into one-to-many relationship房间插入一对多关系
【发布时间】:2021-12-12 14:39:06
【问题描述】:

在尝试使用中间类来模拟 Room 中的实体关系时,我遇到了一个问题。虽然文档描述了如何从一对多关系中获取,但没有描述如何插入。

我假设这不能自动完成,因此我们需要一个查询来插入父项,检索父项的 ID 并将其分配给子项的外键,然后插入子项。

问题是我不确定在哪里放置这样的查询。如果我将它包含在我的 DAO 中,那么我将不得不包含用于插入子项的多余方法。如果我将它包含在我的存储库中,这会使测试变得非常困难(如果不是不可能的话)。

有谁知道如何解决这个问题?

【问题讨论】:

    标签: kotlin android-room


    【解决方案1】:

    我假设这不能自动完成,因此我们需要一个查询来插入父项,检索父项的 ID 并将其分配给子项的外键,然后插入子项。

    第一个假设是正确的,即您必须提供父级的 id(否则如何知道父级)。

    但是,您必须查询父级的第二个假设并非总是如此,在您描述的场景中也并非如此。如果在插入父对象时,如果使用便利 @Insert 作为 Long 或 Long 数组(如果插入多个父对象),则返回 id。

    例如,假设你有:-

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

    @Entity
    data class Child(
        @PrimaryKey
        var id: Long? = null,
        var parentId: Long,
        var otherdata: String
    )
    

    还有一个带有@Dao 注释的类:-

    @Insert
    fun insert(parent: Parent): Long
    @Insert
    fun insert(child: Child): Long
    

    然后您可以使用以下内容,而无需查询Parent:-

        var lastParent = dao.insert(Parent(other = "Parent1 other data"))
        dao.insert(Child(parentId = lastParent, otherdata = "Child1 other data"))
        dao.insert(Child(parentId = lastParent, otherdata = "Child2 other data"))
    
        // Insert a Child with it's Parent together
        dao.insert(Child(
            parentId = dao.insert(Parent(other = "Parent2 other data")),
            otherdata = "Child3 other data"
        ))
    
    • 请注意,即使您将 id 定义为 Int,插入时也会返回 Long。
      • 将 Int 用于 id 是不正确的,因为 SQLite 将 id 存储为 64 位有符号整数,这对于 Int 来说太大了。
        • 但是,直到 id 达到对于 Int(32 位签名)而言太大的值(即大于 2,147,483,647)时才会出现问题。

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多