【问题标题】:Android Room onDelete cascade not working properlyAndroid Room onDelete 级联无法正常工作
【发布时间】:2020-04-23 14:33:22
【问题描述】:

所以我有一个包含 Deck 表、Card 表和 DeckCard 表的数据库,因为这两者之间存在多对多的关系......当我尝试删除一个牌组时,我删除了 DeckCard 行,其中id 匹配并且我设置了外键 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);

}

【问题讨论】:

    标签: android android-room sql-delete


    【解决方案1】:

    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 或 OnOpen)。

    【讨论】:

      猜你喜欢
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 2017-03-10
      • 2012-09-13
      相关资源
      最近更新 更多