0

请耐心等待,这是一个棘手的问题,我发现的哪些资源并不能真正帮助我解决问题。

我正在尝试在 Kotlin 上构建一个面向房地产的应用程序。它必须在某个点显示RecyclerView具有多个对象类别的 a(例如:房屋、公寓、地块、建筑物等)

我见过多个设计为接受多个类的 RV 示例,但我正在努力将数据库和在表和 POJO 之间转换的中间类放在一起。

到目前为止,我已经想到了以下几点:

  • 我必须有一个 Properties 表来存储每个对象的唯一 ID,以及它的类型的另一个标识符和每个属性共有的一系列值(例如,地址、价格等)
  • 对于每个实体类型,我必须有一个表格,可以独立列为房地产项目(例如,房子、公寓、一块土地、建筑物,你有什么)。这些表上的每一行都有一个主外键,引用其在 Properties 表上的等效项。

现在是意想不到的哈瓦那人。我决定在RecyclerViewGoogle 为像我这样的新手准备的 Kotlin 代码实验室的基础上开始草拟我的项目。其中数据以这种方式从数据库中检索:

this.plots = Transformations.map(database.RealtorDao.getPlots()) { it.asDomainModel() }

当数据库向您吐出的列表中的对象都是单一类型时,这很顺利,但是如果您需要它们属于不同的类以便适配器可以区分它们会发生什么?

或者唯一的方法是构建一个包含大约一百列的巨大表,其中到处都有空值,并且仅在以前面描述的方式解析对象之后才对对象进行排序?

4

1 回答 1

0

我把头撞在这堵墙上,直到我厌倦了听到挤压的声音。我无法让 Room DB 返回多个类的对象列表,因此我不得不采用更脏的方法。

如果我只使用数据库类,那么我可能已经破解了它,但是尝试将此类类的对象转换为 POJO 以使用一些复杂的东西。

我发现的解决方法是制作一个主房地产课程,并接受它在数据库上会有很多很多的空字段。虽然与理想相去甚远,但它确实有效。

数据库对象类:

open class DatabaseProperty
{
    @ColumnInfo(name = COL_TYPE)
    @SerializedName(COL_TYPE)
    @Expose
    var type: String? = null

    @ColumnInfo(name = COL_ADDRESS)
    @SerializedName(COL_ADDRESS)
    @Expose
    var address: String? = null

    @ColumnInfo(name = COL_OWNER)
    @SerializedName(COL_OWNER)
    @Expose
    var owner: String? = null

    @ColumnInfo(name = COL_PRICE_FINAL)
    @SerializedName(COL_PRICE_FINAL)
    @Expose
    var priceFinal: Long? = null

    @ColumnInfo(name = COL_PRICE_QUOTED)
    @SerializedName(COL_PRICE_QUOTED)
    @Expose
    var priceQuoted: Long? = null

    /**
     * No args constructor for use in serialization
     */
    constructor()

    @Ignore
    constructor
    (
        type: String,
        address: String,
        owner: String,
        priceFinal: Long,
        priceQuoted: Long
    ) : super() {
        this.type = type
        this.address = address
        this.owner = owner
        this.priceFinal = priceFinal
        this.priceQuoted = priceQuoted
    }
}

@Entity
(
    tableName = TABLE_RE,
    indices =
    [
        Index(value = [COL_RE_ID], unique = true)
    ],
    foreignKeys =
    [
        ForeignKey
        (
            entity = DatabaseRealEstate::class,
            parentColumns = arrayOf(COL_RE_ID),
            childColumns = arrayOf(COL_PARENT_ID),
            onDelete = ForeignKey.NO_ACTION
        )
    ]
)
data class DatabaseRealEstate
(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = COL_RE_ID)
    var id: Int? = null,

    @ColumnInfo(name = COL_PARENT_ID)
    var parent_id: Int? = null,

    @Embedded(prefix = RE)
    var property: DatabaseProperty? = null,

    @ColumnInfo(name = COL_PARCEL_FRONT)        // Plot front
    @SerializedName(COL_PARCEL_FRONT)
    @Expose
    var front: Float? = null,

    @ColumnInfo(name = COL_PARCEL_SIDE)         // Plot side
    @SerializedName(COL_PARCEL_SIDE)
    @Expose
    var side: Float? = null,

    @ColumnInfo(name = COL_AREA)                // Plot area
    @SerializedName(COL_AREA)
    @Expose
    var area: Float? = null,

    @ColumnInfo(name = COL_CATASTER)
    @SerializedName(COL_CATASTER)
    @Expose
    var cataster: String? = null,

    @ColumnInfo(name = COL_ZONIFICATION)
    @SerializedName(COL_ZONIFICATION)
    @Expose
    var zonification: String? = null,
)

data class RealEstateWithSubunits
(
    @Embedded
    val re: DatabaseRealEstate? = null,

    @Relation
    (
        parentColumn = COL_RE_ID,
        entityColumn = COL_PARENT_ID,
        entity = DatabaseRealEstate::class
    )
    var subunits: List<DatabaseRealEstate>? = null,

    @Relation
    (
        parentColumn = COL_RE_ID,
        entityColumn = COL_PARENT_ID,
        entity = DatabaseChamber::class
    )
    var chambers: List<DatabaseChamber>? = null
)

fun List<RealEstateWithSubunits>.asRESUBDomainModel() : List<RealEstate>
{
    return map { obj ->
        RealEstate(
            id = obj.re!!.id!!,
            type = obj.re.property!!.type!!,
            address = obj.re.property!!.address!!,
            owner = obj.re.property!!.owner!!,
            priceFinal = obj.re.property!!.priceFinal!!,
            priceQuoted = obj.re.property!!.priceQuoted!!,
            parent_id = obj.re.parent_id,
            front = obj.re.front,
            side = obj.re.side,
            area = obj.re.area,
            cataster = obj.re.cataster,
            zonification = obj.re.zonification,
            chambers = obj.chambers!!.asChamberDomainModel(),
            subunits = obj.subunits!!.asREDomainModel()
        )
    }
}

fun List<DatabaseChamber>.asChamberDomainModel(): List<Chamber>
{
    return map {
        Chamber(
            id = it.id,
            parent_id = it.parent_id,
            front = it.front,
            side = it.side,
            area = it.area
        )
    }
}

fun List<DatabaseRealEstate>.asREDomainModel(): List<RealEstate>
{
    return map { obj ->
        RealEstate(
            id = obj.id!!,
            type = obj.property!!.type!!,
            address = obj.property!!.address!!,
            owner = obj.property!!.owner!!,
            priceFinal = obj.property!!.priceFinal!!,
            priceQuoted = obj.property!!.priceQuoted!!,
            parent_id = obj.parent_id,
            front = obj.front,
            side = obj.side,
            area = obj.area,
            cataster = obj.cataster,
            zonification = obj.zonification,
            chambers = ArrayList(),
            subunits = ArrayList()
        )
    }
}

模型对象类:

interface BaseProperty {
    var id: Int
    var type: String
    var address: String
    var owner: String
    var priceFinal: Long
    var priceQuoted: Long
}

data class RealEstate(
    override var id: Int = -1,
    override var type: String = "",
    override var address: String = "",
    override var owner: String = "",
    override var priceFinal: Long = 0,
    override var priceQuoted: Long = 0,
    var parent_id: Int?,
    var front: Float?,
    var side: Float?,
    var area: Float?,
    var cataster: String?,
    var zonification: String?,
    var subunits: List<RealEstate>? = null,
    var chambers: List<Chamber>? = null
) : BaseProperty
{
    fun hasParent() : Boolean
    {
        if (parent_id == null)
        {
            return false
        }
        return true
    }
}

我还没有找到更好的方法,所以如果有人找到了,我会张开双臂欢迎它。

于 2020-10-22T18:14:29.930 回答