android - Android Room onDelete 级联无法正常工作
问题描述
所以我有这个数据库,其中包含一个 Deck 表、一个 Card 表和一个 DeckCard 表,因为这两者之间存在多对多的关系......当我尝试删除一个牌组时,我删除了 id 匹配的 DeckCard 行我已经设置了外键 onDelete = CASCADE 但它没有删除套牌有什么建议吗?这是我的 n 到 n 区别的存储库
public class DeckCardRepository {
private DeckWithCardsDao mDeckWithCardsDao;
public void delete(Deck deck){
DecksDatabase.databaseWriteExecutor.execute(() ->
mDeckWithCardsDao.delete(deck.getId()));
}
}
甲板类
@Entity(tableName = "decks")
public class Deck implements Serializable {
@PrimaryKey
private long id;
private String keyforgeId;
private String name;
@TypeConverters({ExpansionTypeConverter.class})
private Expansion expansion;
private int creatureCount;
private int actionCount;
private int artifactCount;
private int upgradeCount;
private int sasRating;
private int powerLevel;
private int chains;
private int wins;
private int losses;
private int totalPower;
private int totalArmor;
private int localWins;
private int localLosses;
}
卡类
Entity(tableName = "cards")
public class Card implements Serializable {
@PrimaryKey
@NonNull
private String id;
private String card_title;
private String card_type;
@TypeConverters({HouseArrayTypeConverter.class})
private House house;
private String card_text;
private int amber;
private String front_image;
}
卡组类
Entity(tableName = "cards_deck_join",
primaryKeys = {"cardId", "deckId"},
foreignKeys = {
@ForeignKey(
entity = Card.class,
parentColumns = "id",
childColumns = "cardId"),
@ForeignKey(onDelete = CASCADE,
entity = Deck.class,
parentColumns = "id",
childColumns = "deckId"),
})
public class CardsDeckRef {
@NonNull
private String cardId;
private long deckId;
private int count;
public CardsDeckRef(String cardId, long deckId, int count) {
this.cardId = cardId;
this.deckId = deckId;
this.count = count;
}
}
我的道
@Dao
public interface DeckWithCardsDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void add(CardsDeckRef cardsDeckRef);
@Transaction
@Query("SELECT * FROM cards INNER JOIN cards_deck_join" +
" ON cards.id=cards_deck_join.cardId WHERE cards_deck_join.deckId =:deckId")
LiveData<List<Card>> getCardsForDeck(final long deckId);
@Query("DELETE FROM cards_deck_join WHERE cards_deck_join.deckId=:deckId ")
void delete(final long deckId);
}
解决方案
ON CASCADE DELETE
(即onDelete = CASCADE
添加到表中的内容)如果删除父级,则将删除子级。如果一个孩子或即使所有孩子都被删除,它也不会删除父母。
而不是删除一个牌组和所有与牌组相关的cards_deck_join行,你应该使用
@Query("DELETE FROM decks WHERE id=:deckId ")
void delete(final long deckId);
然后甲板的删除将级联到cards_deck_join表。
如果您想在从cards_deck_join 中删除后没有子级的情况下自动删除一个牌组,那么您可以使用TRIGGER ,例如
CREATE TRIGGER IF NOT EXISTS delete_empty_deck
AFTER DELETE ON card_deck_join
BEGIN
DELETE FROM decks
WHERE (SELECT count(*) FROM card_deck_join WHERE deckid = old.deckid) = 0 AND decks.id = old.deckid;
END;
- 由于房间不支持触发器的生成(据我所知,当它生成一些触发器时 FTS 除外),您必须在房间之外添加触发器(例如,通过覆盖 onCreate 或打开)。
推荐阅读
- ngrx - 整个州或部分的 ngrx/实体
- python - 在张量流图中手动设置权重
- c# - WPF XAML 文本框插入符号位置在末尾
- laravel - 如何告诉`whereHas`查询子查询表在另一个数据库中(多租户)
- javascript - 黑客可以通过什么方式获取存储在客户端变量中的敏感信息?
- php - 我为图像创建了一个下载功能,但它的扩展名是 .php
- reactjs - 组件受其他组件的道具影响?
- android - Android - Spannable: Unable to set multiple spans at once
- javascript - 根据屏幕位置更改 InnerHTML?
- mongodb - $facet 是如何工作的?