Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Room onDelete级联无法正常工作_Android_Android Room_Sql Delete - Fatal编程技术网

Android Room onDelete级联无法正常工作

Android Room onDelete级联无法正常工作,android,android-room,sql-delete,Android,Android Room,Sql Delete,所以我有这个数据库,它有一个组表,一个卡表和一个DeckCard表,因为这两个表之间有一个多对多的关系…当我试图删除一个组时,我删除了id匹配的DeckCard行,我设置了外键onDelete=CASCADE,但它没有删除组。有什么建议吗? 这是我的n对n区分的存储库 public class DeckCardRepository { private DeckWithCardsDao mDeckWithCardsDao; public void delete(Deck deck

所以我有这个数据库,它有一个组表,一个卡表和一个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;
    }
}

MyDao

@Dao
使用CardSDAO的公共接口{
@插入(onConflict=OnConflictStrategy.IGNORE)
无效添加(cardseckref cardseckref);
@交易
@查询(“选择*自卡片内部连接卡片\u卡片组\u连接”+
“在卡片上。id=卡片\u卡片组\u连接.cardd,其中卡片\u卡片组\u连接.deckId=:deckId”)
LiveData getCardsForDeck(最终的长deckId);
@查询(“从卡\u组\u连接中删除,其中卡\u组\u连接。deckId=:deckId”)
作废删除(最终长deckId);
}

关于级联删除
(即
onDelete=CASCADE
添加到表中的内容)将在删除父项时删除子项。如果删除了一个子项,甚至删除了所有子项,它也不会删除父项

而是删除一个牌组,并将所有牌组与您应该使用的牌组关联的行连接起来

@Query("DELETE FROM decks WHERE id=:deckId ")
void delete(final long deckId);
然后,该组的删除将级联到cards\u deck\u join表


如果你想自动删除一个牌组,如果从牌组中删除后没有子牌,那么你可以使用触发器例如

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;
  • 由于room不支持触发器的生成(据我所知,FTS除外,因为它确实生成了一些触发器),因此您必须在room之外添加触发器(例如,通过覆盖onCreate或OnOpen的回调)
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;