#kotlin #android-room #android-room-relation
Вопрос:
У меня есть эти отношения:
Клиент > Адрес
Клиент > Собственность
Недвижимость > Адрес
Поэтому я пытаюсь сделать это:
data class DetailedCustomerInformation(
@Embedded
val customer: Customer,
@Relation(parentColumn = "addressId", entityColumn = "id")
val address: Address,
@Relation(parentColumn = "propertyId", entityColumn = "id")
val property: PropertyWithAddress
) : Serializable
Где свойство с адресом находится
data class PropertyWithAddress(
@Embedded
var property: Property,
@Relation(parentColumn = "addressId", entityColumn = "id")
var address: Address
)
Но это не работает, потому что PropertyWithAddress не является объектом/представлением базы данных.
Мой вопрос в том, можно ли отобразить эти отношения, используя какой-то механизм помещения. Я знаю, что могу выполнять запросы напрямую и загружать объекты, но я хотел бы знать, поддерживает ли это каким-либо образом room.
Ответ №1:
Можно ли отобразить этот сценарий непосредственно в комнате?
Да, и вы были очень близки к разгадке.
Но это не работает, потому что PropertyWithAddress не является объектом/представлением базы данных.
Вам необходимо указать таблицу/сущность родителя, из которой должен быть извлечен POJO (Свойство) в параметре @Relation
using entity=
. (т. Е. Ожидается сущность, а PropertyWithAddress не является сущностью)
напр.
data class DetailedCustomerInformation(
@Embedded
val customer: Customer,
@Relation(entity = Address::class,parentColumn = "addressId", entityColumn = "id")
val address: Address,
@Relation(entity = Property::class, parentColumn = "propertyId",entityColumn = "id")
val propertyWithAddress: PropertyWithAddress
)
- Обратите внимание, что я всегда кодирую
entity =
параметр, даже если он не требуется
Таким образом, используя вышесказанное и приближения ваших других сущностей и класса @Dao :-
@Dao
abstract class CustomerDao {
@Insert
abstract fun insert(customer: Customer): Long
@Insert
abstract fun insert(address: Address): Long
@Insert
abstract fun insert(property: Property): Long
@Query("SELECT * FROM customer")
abstract fun getDetailedCustomerInformation(): List<DetailedCustomerInformation>
}
а затем используйте следующее в действии (для удобства и краткости выполните в основном потоке) :-
db = TheDatabase.getInstance(this)
customerDao = db.getCustomerDao()
var a1 = customerDao.insert(Address(addressDetails = "This is address 1"))
var a2 = customerDao.insert(Address(addressDetails = "This is address 2"))
var a3 = customerDao.insert(Address(addressDetails = "This is address 3"))
var p1 = customerDao.insert(Property(addressId = a1,propertyDetails = "This is property1"))
var p2 = customerDao.insert(Property(addressId = a2,propertyDetails = "This is property 2"))
customerDao.insert(Customer(addressId = a3,propertyId = p1,customerDetails = "This is customer 1"))
customerDao.insert(Customer(addressId = a1,propertyId = p2,customerDetails = "This is customer 2"))
var TAG = "CUSTINFO"
for(dci: DetailedCustomerInformation in customerDao.getDetailedCustomerInformation()) {
Log.d("CUSTINFO","Customer Details = ${dci.customer.customerDetails}"
"ntCustomer's address is ${dci.address.addressDetails}"
"ntProperty is ${dci.propertyWithAddress.property.propertyDetails} address is ${dci.propertyWithAddress.address.addressDetails}"
)
}
Результат, выводимый в журнал, является :-
D/CUSTINFO: Customer Details = This is customer 1
Customer's address is This is address 3
Property is This is property1 address is This is address 1
D/CUSTINFO: Customer Details = This is customer 2
Customer's address is This is address 1
Property is This is property 2 address is This is address 2