【问题标题】:Retrieve/insert many-to-many relationship object from Room (Kotlin)从 Room (Kotlin) 检索/插入多对多关系对象
【发布时间】:2020-09-05 15:08:30
【问题描述】:

我正在使用 Room 做一个小项目。基本上,一个食谱可以有许多成分,而一个成分可以属于许多食谱。

这些是我的实体,在多对多关系部分建议为Documentation

@Entity
data class Recipe(
    var name: String
) {
    @PrimaryKey(autoGenerate = true)
    var recipeUID: Int = 0
}

@Entity
data class Ingredient(
    var name: String
) {
    @PrimaryKey(autoGenerate = true)
    var ingredientUID: Int = 0
}

@Entity(primaryKeys = ["recipeUID", "ingredientUID"])
data class RecipeIngredientCrossRef(
    val recipeUID: Int,
    val ingredientUID: Int
)


//Docs suggested @Junction but that causes error for using tag inside @Relation...
data class RecipeWithIngredients(
        @Embedded
        val recipe: Recipe,
        @Relation(
            parentColumn = "recipeUID",
            entity = Ingredient::class,
            entityColumn = "ingredientUID",
            associateBy = Junction(
                value = RecipeIngredientCrossRef::class,
                parentColumn = "recipeUID",
                entityColumn = "ingredientUID"
                )
        )
        var ingredients: List<Ingredient>
    )

然后我尝试按照相同的文档制作 Dao 函数,但它只描述了如何检索,我在这里应用了它:

@Transaction
@Query("SELECT * FROM recipe")
suspend fun getAllRecipes(): List<RecipeWithIngredients>

然后我发现这个Medium article 解释了我想要实现的目标,这导致我为插入函数编写了这个:

 @Insert(onConflict = REPLACE)
        suspend fun insert(join: RecipeIngredientCrossRef): Long

在插入之前一切正常,我已经验证信息正在被插入,但是我在检索时做错了,因为它什么也没返回。我可以看到它什么都不返回的原因是因为没有任何东西插入到该表中(因为我的插入方法将它放入 RecipeIngredientCrossRef 表而不是配方表),这让我相信错误的部分实际上是我的插入方法。

所以基本上我的问题是:如何检索包含配方对象的 RecipeWithIngredients 对象列表,其中包含成分对象列表作为成员变量?

Room CRUD 功能上的 documentation 没有提及任何有关此类关系的内容。

我一直在 Youtube、here、文档和 Medium 上寻找几个小时,但到目前为止没有任何效果。谁能给我一些启发或指出正确的方向。

【问题讨论】:

    标签: android kotlin many-to-many android-room


    【解决方案1】:

    您是否忘记为您的RecipeIngredient 表添加插入方法?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertRecipe(recipe: Recipe): Long
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertIngredient(ingredient: Ingredient): Long
    

    所以要获得非空的RecipeWithIngredients 结果,应该有三个表,其中包含您从 dao 插入的数据 - RecipeIngredientRecipeIngredientCrossRef。当然,它们应该包含相互匹配的 id-s。

    【讨论】:

    • 当你第一天给我答案时,我花了六天时间寻找答案。好吧,至少现在我可以欣赏它和你更多......并且更好地理解为什么这是正确的答案,我真的需要开始信任其他人。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    相关资源
    最近更新 更多