Можно ли отобразить этот сценарий непосредственно в комнате?

#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