房间关系扩展时指定列名

时间:2020-10-26 20:48:50

标签: kotlin android-room

我正在处理我的会议室数据库中的一些数据集,我的方法是拥有一张表,其中包含有关名为DatasetInfo的数据集的信息,该数据集用于存储名称,存储的值类型,id等内容;第二张表将值存储在3列中:(id,日期,值)。此有序三元组定义为DatasetValue实体。在这里,(日期,值)是我要绘制的有序对。

要绘制这些有序对,我必须将它们转换为Entry对象的列表,其中Entry取值xy。查询数据库并仅请求List<Entry>最为有意义,因为现在我请求List<DatasetValue>,然后必须将该结果映射到List<Entry>,这是不必要的。

我查询数据集信息表DatasetInfo如下:

data class DatasetWithValues(
    @Embedded
    var datasetInfo: DatasetInfo,
    @Relation(
        parentColumn = DATASET_COLUMN_DATASET_ID,
        entityColumn = VALUES_COLUMN_ID,
        entity = DatasetValue::class,
    )
    var values : List<Entry>
)

现在,如上所述,Entry具有值xy,并且Dataset分别称为datevalue。当然,当我请求这种关系时,它将失败,因为它不知道如何将具有列iddatevalue的表中的值分配给对象其中需要xy。因此,我定义了一个新类:

class DatasetEntry(
    @ColumnInfo(name = "date") 
    var date : Float,
    @ColumnInfo(name = "value") 
    val value : Float
) : Entry(date, value)

,然后进行以下调整:

//var values : List<Entry>
var values : List<DatasetEntry> 

那什么也没做。该代码无法编译,因为:

SQL错误或缺少数据库(无此列:x)

好吧,如果我改为写:

class DatasetEntry(
    @ColumnInfo(name = "date")
    var date : Float,
    @ColumnInfo(name = "value")
    val value : Float
) : Entry(){
    init{
        x = date
        y = value
    }
}

那也没有帮助,同样的错误。即使我删除了该init呼叫,它仍然希望x

该图变厚了,因为在Entry内可以看到x被声明为私有。所以我完全不知道这里发生了什么。 Room怎么知道要寻找x?除了将表中的列重命名为xy以外,还有其他解决方法吗?

1 个答案:

答案 0 :(得分:0)

除了将表中的列重命名为x和y之外,是否还有其他解决方法?

如果您有这样的选择,那将是最简单的。仍然可以考虑一些选择:

1。将会议室的结果映射到所需的人

因此,您要求Room提供一些raw结果,然后将其映射到ready。为此,您添加了2个类:

data class DatasetWithValuesRaw(
    @Embedded
    var datasetInfo: DatasetInfo,
    @Relation(
        parentColumn = DATASET_COLUMN_DATASET_ID,
        entityColumn = VALUES_COLUMN_ID,
    )
    var values : List<DatasetValue>
)

data class DatasetWithValuesReady(
    var datasetInfo: DatasetInfo,
    var values : List<Entry>
)

假设您有一个dao方法:

Query("select * ....")
fun getRawData(): List<DatasetWithValuesRaw>

对于映射,您使用:

fun getReadyData() = 
   getRawData().map { item -> 
    DatasetWithValuesReady(item.datasetInfo, 
       item.values.map { Entry(x = it.date, y = it.value) 
   }) }

2。用显式查询替换Room的@Relation

这不是您真正想要的,但仍然是一个选择。 使用这样的类:

data class DatasetWithSeparateValues(
    @Embedded
    var datasetInfo: DatasetInfo,
    @Embedded
    var value : Entry // <----- it's not a list, just a single value
)

,然后在dao中使用显式列名称(xy)设置查询。像这样的东西:

Query("SELECT *, values.date as x, values.value as y FROM dataset LEFT JOIN values on dataset.DATASET_COLUMN_DATASET_ID = values.VALUES_COLUMN_ID")
fun getData(): List<DatasetWithSeparateValues>

因此,您将获得一个列表,但是如果有一个包含5个值的数据集,您将在列表内获得5个具有相同数据集和单独值的项目。之后,您可以使用Kotlin集合的方法(例如groupBy)以某种方式美化结果