【问题标题】:Let room handle@Insert of objects with @Embedded and @Relation annotations让房间处理带有@Embedded 和@Relation 注释的对象的@Insert
【发布时间】:2020-02-28 18:14:42
【问题描述】:

我已经阅读了大量关于房间和外键的问答和文章,我几乎确信我实际上无法实现我想要做的事情。此外,大多数示例/教程仅解释选择查询。

所以,有一个经典的一对多关系,我想用@Embedded 和@Relation 定义一个对象,以获得包含对象列表的对象的“一次性”插入方法。 为了更清楚:

许可证:

@Entity(tableName = "licence")
data class Licence(
  @PrimaryKey(autoGenerate = true)
  @ColumnInfo(name = "licence_id")
  var licenceId: Int,
  @ColumnInfo(name = "expiration_date")
  var expirationDate: Date
  //other attributes  )

许可证配置:

@Entity(
foreignKeys = [
    ForeignKey(
        entity = Licence::class,
        parentColumns = ["licence_id"],
        childColumns = ["licence_reference"],
        onDelete = ForeignKey.CASCADE,
        onUpdate = ForeignKey.CASCADE
    )],
tableName = "licence_configurations")
data class LicenceConfig(
  @PrimaryKey(autoGenerate = true)
  @ColumnInfo(name = "licence_config_id")
  var licenceConfigId: Int,
  @ColumnInfo(name = "licence_reference")
 var licenceId: Int
//other attributes  )

LicenceWithConfigurations

data class LicenceWithConfigurations(
@Embedded
val licence: Licence,
@Relation(
    parentColumn = "licence_id",
    entityColumn = "licence_reference",
    entity = LicenceConfig::class)
val licenceConfig: List<LicenceConfig>?)

我要做的是避免@Transaction 并为许可证执行第一次插入,检索 id,为每个许可证配置设置 id 并执行另一次插入。 相反,我想在 DAO 中使用类似的方法:

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertLicenceWithConfigurations(licenceWithConfigurations: LicenceWithConfigurations)

现在错误是“FOREIGN KEY 约束失败(代码 787 SQLITE_CONSTRAINT_FOREIGNKEY)”,所以我为 LicenceConfig 类指定了@Index,然后尝试在另一个字段上设置外键(因为我已经阅读了自动生成的 id 为外键它不起作用)但仍然不起作用。我可以这样做还是应该返回 @Transaction 并手动处理插入?

【问题讨论】:

    标签: android kotlin android-room


    【解决方案1】:

    我自己让它工作。 正如我认为的主要问题是用作外键的许可证的自动生成的 int 键。一个“静态”字符串并在 @Insert 方法中拆分两个对象就可以了。 我把它留在这里,希望它对某人有所帮助:

    许可证:

    @Entity(tableName = "licence")
    data class Licence(
    @PrimaryKey
    @ColumnInfo(name = "function_id")
    var functionId: String,
    
    @ColumnInfo(name = "expiration_date")
    var expirationDate: Date,
    //more attributes )
    

    许可证配置:

    @Entity(
    foreignKeys = [
        ForeignKey(
            entity = Licence::class,
            parentColumns = ["function_id"],
            childColumns = ["licence_reference"],
            onDelete = ForeignKey.CASCADE,
            onUpdate = ForeignKey.CASCADE
        )],tableName = "licence_configurations")
    data class LicenceConfig(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "licence_config_id")
    var licenceConfigId: Int,
    
    @ColumnInfo(name = "licence_reference")
    var licenceId: Int
    //more attributes )
    

    LicenceWithConfigurations:

    data class LicenceWithConfigurations(
    @Embedded
    val licence: Licence,
    @Relation(
    parentColumn = "licence_id",
    entityColumn = "licence_reference",
    entity = LicenceConfig::class)
    val licenceConfig: List<LicenceConfig>?)
    

    LicenceDao:

     @Transaction
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertLicenceWithConfigurations(licence:Licence, licenceConfigurations: List<LicenceConfig>?)
    
    @Transaction
    @Query("SELECT * FROM licence")
    suspend fun getAllLicencesWithConfigurations(): List<LicenceWithConfigurations>
    

    【讨论】:

      猜你喜欢
      • 2018-06-29
      • 2020-05-13
      • 2018-03-26
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多