Комната: удаление ForeignKey или установка ForeignKey в значение по умолчанию - PullRequest
0 голосов
/ 22 октября 2018

У меня есть следующие объекты:

@Entity(indices  = {@Index("address")},
    foreignKeys = @ForeignKey(
    entity = Address.class,
    parentColumns = "address",
    childColumns = "address",
    onUpdate = CASCADE,
    onDelete = SET_DEFAULT))
public class Human {
    @PrimaryKey(autoGenerate = true)
    public long id;

    @NonNull
    public String name;

    @NonNull
    public String address;
}

@Entity
public class Address {

    @PrimaryKey
    @NonNull
    public String address;

    public int someInt;
}

Я добавляю «людей» с разными адресами, которые позже пытаюсь удалить или изменить, используя:

@Insert(onConflict = REPLACE)
void add(Human human);

Параметры, которые я вижу ипроблемы с ними:

  1. У меня есть список адресов, один из которых «по умолчанию».Когда я удаляю адрес, я бы хотел, чтобы «Люди», находящиеся на удаленном адресе, «переместились» в «по умолчанию».Я использовал:

    @Query("delete from Address where address = :address")
    void deleteAddress(String address);
    

, так что onDelete = SET_DEFAULT, похоже, не работает так, как я себе представлял, если я установил значение по умолчанию для адреса в Human Entity.

Этов настоящее время происходит сбой с: Сбой ограничения NOT NULL.

Альтернативой удалению может быть изменение адреса и установка его в значение «по умолчанию» и, таким образом, слияние с существующей записью «по умолчанию».Я попытался:

@Query("update Address SET address = :address WHERE address = :addressToEdit")
void editAddress(String addressToEdit, String newAddress);

В настоящее время это не удается с: Не удалось выполнить ограничение UNIQUE. , поскольку, очевидно, уже есть адрес с таким именем.

Установка адреса @Nullable в обеих сущностях.Таким образом, адрес «по умолчанию» является нулевым.Это добавляет дополнительную сложность моему решению (не хотелось бы), и кажется, что я не могу запросить людей с пустым адресом, используя следующий код, потому что он ничего не возвращает.

@Query("select * from Human where address = :address")
LiveData<List<Human>> getHumans(String address);

Как мне установить этот параметр по умолчанию для удаленного адреса (внешнего ключа)?

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Мое лучшее решение, которое работает до сих пор, - использовать третий вариант из вопроса с:

    @Query("select * from Human where address is NULL")
    LiveData<List<Human>> getAllHumansWithNullAddress();

Как и при использовании NULL по умолчанию.

Address остается тем жено человек становится:

@Entity(indices  = {@Index("address")},
    foreignKeys = @ForeignKey(
    entity = Address.class,
    parentColumns = "address",
    childColumns = "address",
    onUpdate = CASCADE,
    onDelete = SET_NULL))
public class Human {
    @PrimaryKey(autoGenerate = true)
    public long id;

    @NonNull
    public String name;

    @Nullable
    public String address;
}
0 голосов
/ 31 октября 2018

в настоящее время комната не поддерживает действие onDelete = SET_DEFAULT, и комната обрабатывает его так же, как onDelete = SET_NULL, поэтому я предлагаю следующее: -

@Entity(foreignKeys = @ForeignKey(
                entity = Address.class,
                parentColumns = "address",
                childColumns = "fk_address_id",
                onUpdate = CASCADE,
                onDelete = SET_DEFAULT))
public class Human {
    @PrimaryKey(autoGenerate = true)
    public long id;

    @NonNull
    public String name;


    @Nullable
    public String getFk_address_id() {
        return fk_address_id;
    }

    public void setFk_address_id(@Nullable String fk_address_id) {
        this.fk_address_id = fk_address_id;
    }

    //default address doesn't work on delete as room doesn't support
    // on delete set default and treat it like set null
    @Nullable
    public String fk_address_id = "default address";

    public Human(@NonNull String name,  @Nullable String fk_address_id) {
        this.name = name;
        this.fk_address_id = fk_address_id;
    }

}

, а вот адрес объекта, где поле адресауникальный.

@Entity(indices = {@Index(value = {"address"},
        unique = true)})
public class Address {
    public void setAddress(@NonNull String address) {
        this.address = address;
    }

    @PrimaryKey(autoGenerate = true)
    @NonNull
    int id;


    public String address = "default address";


    public int someInt;

    public Address(@NonNull String address, int someInt) {
        this.address = address;
        this.someInt = someInt;
    }

}

и в HumanDao вы можете получить нулевой ссылочный адрес и обновить его до адреса по умолчанию.

HumanDao:

@Query("SELECT * FROM Human where fk_address_id IS NULL")
Human[] getNullRef();

AddressDao:

@Update
void updateAddresses(Address... addresses);

AsyncTask class

protected Void doInBackground(Void... voids) {
            AppDatabase db = AppDatabase.getDatabase(getApplicationContext());
            Address address = db.addressDao().getAddress("address to delete");
            if(address != null) {
                db.addressDao().delete(address);
                Human [] humans = db.humanDao().getNullRef();
                for(int i =0; i < humans.length; i++) humans[i].setFk_address_id(DEFAULT_ADDRESS);
                db.humanDao().updateHumans(humans);
            }
            return null;
        }
0 голосов
/ 29 октября 2018

Я предлагаю изменить адресную сущность и добавить поле идентификатора в виде целочисленного автоматического увеличения.затем в Human Entity вы можете ссылаться на адреса по полю id.поэтому перед удалением записи адреса вы можете обновить записи о людях, используя ссылку, которую вы хотите удалить, по идентификатору ссылки по умолчанию, например: 1, затем вы можете удалить эту запись адреса по ее идентификатору.Здесь вы можете решить проблему с уникальным ограничением адреса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...