Android Room:如何查询没有外键列的相关实体

时间:2019-04-25 15:59:42

标签: android android-room

我的数据的组织结构与您通常在SQL数据库中期望的有所不同,但是我无法更改。因此,我有相关的实体,其中父母使用子ID数组引用其子:

data class Parent(
    @PrimaryKey val id: Int,
    val children: List<Int>
)

data class Child(
    @PrimaryKey val id: Int
)

我想拥有一个查询或DAO函数,该函数可以在一次调用中检索父级及其子级。所以我可能必须创建一个组合实体,例如:

data class ParentWithChildren(
    val parent: Parent,
    val children: List<Child>
)

但是推荐的获取结果的方式是什么(最好是LiveData)?是否有@Query批注可以检索结果,或者我必须做类似的事情:

@Query("SELECT * FROM parent WHERE id = :id")
fun getParent(id: Int): LiveData<Parent>

@Query("SELECT * FROM child WHERE id IN (:ids)")
fun getChildren(ids: List<Int>): List<Child>

fun getParentWithChildren(id: String): LiveData<ParentWithChildren> {
    return Transformations.map(getParent(id)) { parent ->
        val children = getChildren(parent.children)
        ParentWithChildren(parent, children)
    }
}

或者还有其他方法吗?非常感谢您提供有关如何以正确的“类似于房间”的方式进行操作的帮助。

1 个答案:

答案 0 :(得分:0)

好吧,到目前为止,我已经使用MediatorLiveData解决了该问题,因为它似乎是合并LiveData的正确工具。因此,我创建了以下(简化的)ViewModel:

class ParentWithChildrenViewModel : ViewModel() {
    val parent: LiveData<Parent>

    val children: LiveData<List<Child>>

    val parentWithChildren = MediatorLiveData<ParentWithChildren>()

    init {
        parent = parentRepository.getParent(id)

        children = Transformations.switchMap(parent) {
            childRepository.getChildren(it.children)
        }

        with (parentWithChildren) {
            addSource(parent) { parent ->
                children.value?.let { children ->
                    value = ParentWithChildren(parent, children)
                }
            }

            addSource(children) { children ->
                parent.value?.let { parent ->
                    value = ParentWithChildren(parent, children)
                }
            }
        }
    }
}

并观察parentWithChildren属性。