我已经基于文档和此medium article与Room建立了多对多关系模型。使用此@Relation,我可以从数据库中检索RecipeWithIngredients或IngredientsWithRecipe对象。为此,我需要在配方表中插入一个配方,在配料表中插入一个配料,然后将两个ID都先插入到参考表中。我认为除了在Dao上使用@Transaction之外,没有其他方法可以完成插入操作,而只是在一个方法上完成所有操作,但是对于删除和更新,我是否也应该能够使用Relation处理这些操作? Room上的文档对我来说似乎有点缺乏,所以我来找你
//Get for recipeWithIngredients object. (This works)
@Transaction
@Query("SELECT * FROM Recipe WHERE recipeID = :ID")
suspend fun getRecipeWithIngredients(ID:Long): RecipeWithIngredients
//Insert recipeWithIngredients object. (I don't see why this wouldn't work)
//IDs are autoGenerated so I can't get them until they are inserted
@Transaction
suspend fun insertRecipeWithIngredients(recipeWithIngredients: RecipeWithIngredients){
val recipeID = insertRecipe(recipeWithIngredients.recipe)
for(ingredient in recipeWithIngredients.ingredients){
val ingredientID = insertIngredient(ingredient)
insertRecipeIngredientRef(recipeID, ingredientID )
}
}
//I could try doing this like the insert but should't there be a way to do it like the get?
@Transaction
@Query("SOME SQL HERE")
suspend fun deleteRecipeWithIngredients(recipeWithIngredients: RecipeWithIngredients)
答案 0 :(得分:1)
除了在Dao上使用@Transaction并仅使用一种方法完成所有操作外,我认为没有其他方法可以插入
您用insertRecipeWithIngredients
实现的想法很有趣,我想它应该可行,但是我不会说这是实现此目的的常用方法。通常,多对多关系是指您有两个单独的实体,即使它们之间没有关系也具有值(例如User
和UserGroup
)。即使在您的用例中,也可能是一个用户首先添加带有简短文本描述和所需步骤的食谱,然后另一个用户将其绑定了配料,因此insertRecipe
和insertRecipeIngredients
应该分开进行。
在此架构中,您应该实现三个单独的insert
方法-第一个用于Recipe
,第二个用于Ingridient
,第三个-用于RecipeIngridientRef
。但是,当然,在您的特定情况下,您可以像上面描述的那样进行操作。
对于删除和更新,我也不能使用“关系”来完成
开箱即用的Room不支持该功能。它仅用于查询。
如果要删除,请从RecipeIngridientRef
中删除引用到特定配方的行,那么使用Foreign Key
标准机制-级联删除就足够了。这样,您只需为食谱实体写delete
,余下的Room&Sqlite会为您完成。
关于更新,文档中确实缺乏建议。选择之一-首先删除具有特定配方的RecipeIngridientRef
中的所有行,然后对RecipeIngridientRef
使用相同的方法插入(事务中的两个操作)。