首页 > 解决方案 > 如何使 PrimaryKey 以一个顺序为多个表生成 id

问题描述

我有 3 个实体(Dishes、Places、Artifacts),它们继承自一个名为 Memory 的抽象类。每个内存最多可以存储 3 张照片(字符串路径),所以我设置了一对多关系 Memory-Photo。照片行包含内存 ID 作为外键,因此它们可以链接在一起。

问题是 Android Room 为每种类型的内存创建单独的表,因此 @AutoGenerate = true 注释为每种类型的内存以 3 个单独的顺序生成 id。

它会导致冲突,因为在数据库中可能有 3 个具有相同 ID 的不同类型的记忆,因此一组新照片将链接到多个记忆。

我想出了一个想法,用创建时间戳制作主键,但这不是最好的主意。也许有一些方法可以同步密钥生成机制或更改我的数据库的计划。

abstract class Memory(@ColumnInfo(name = "favorite") var favorite: Boolean,
    @ColumnInfo(name = "title") var title: String,
    @ColumnInfo(name = "date") var date: Date,
    @ColumnInfo(name = "description") var description: String,
    @Embedded var mapMarker: MapMarker) : Serializable {
    @ColumnInfo(name="id")
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0 }

@Entity(tableName = "artifact_memories")
class ArtifactMemory(favorite: Boolean,
                 title: String,
                 date: Date,
                 description: String,
                 mapMarker: MapMarker) : Memory(favorite, title,
                                                date, description, mapMarker){}


@Entity(tableName = "dish_memories")
class DishMemory(@ColumnInfo(name = "country_of_origin") var originCountry: String,
    @ColumnInfo(name = "type") var dishType: String,
    favorite: Boolean,
    title: String,
    date: Date,
    description: String,
    mapMarker: MapMarker) : Memory(favorite, title,
                                   date, description, mapMarker) {}

@Entity(tableName = "photos")
data class Photo(@ColumnInfo(name="photo_path") var photoPath: String,
    @ColumnInfo(name="memory_id") var memoryId: Long = 0,
    @ColumnInfo(name="is_main") var main: Boolean = false) : Serializable {
    @PrimaryKey(autoGenerate = true) var id: Long = 0 }

如何处理这样的关系?目标是使照片仅保存在一个内存中和/或消除与 id 重复的冲突。

标签: androidandroid-room

解决方案


您可以使用inheritSuperIndices 属性来确保每个子类都继承超类的主键

@Entity(tableName = "artifact_memories",inheritSuperIndices = true)
class ArtifactMemory(favorite: Boolean,
             title: String,
             date: Date,
             description: String,
             mapMarker: MapMarker) : Memory(favorite, title,
                                            date, description, mapMarker){}


@Entity(tableName = "dish_memories",inheritSuperIndices = true)
class DishMemory(@ColumnInfo(name = "country_of_origin") var originCountry: 
String,
@ColumnInfo(name = "type") var dishType: String,
favorite: Boolean,
title: String,
date: Date,
description: String,
mapMarker: MapMarker) : Memory(favorite, title,
                               date, description, mapMarker) {}

@Entity(tableName = "photos",inheritSuperIndices = true)
data class Photo(@ColumnInfo(name="photo_path") var photoPath: String,
@ColumnInfo(name="memory_id") var memoryId: Long = 0,
@ColumnInfo(name="is_main") var main: Boolean = false) : Serializable {
@PrimaryKey(autoGenerate = true) var id: Long = 0 }

推荐阅读