Android Room 获取数据,其中交叉引用数据类具有第三方元素

问题描述

遇到问题,我在交叉引用类中有第三方字段。 我有一个 项目实体数据类:

@Entity(tableName = "projects")
data class Project(

        @PrimaryKey(autoGenerate = true)
        val projectId: Int = 0,var title: String,var details: String,var date: Date,var price: Int
)

记录实体数据类:

@Entity(tableName = "records")
data class Record (

        @PrimaryKey(autoGenerate = true)
        val recordId: Int,var price: Int,)

交叉引用实体数据类

@Entity(
        tableName = "cross_ref",primaryKeys = ["projectId","recordId"],foreignKeys = [
                ForeignKey(
                        entity = Project::class,parentColumns = ["projectId"],childColumns = ["projectId"]
                ),ForeignKey(
                        entity = Record::class,parentColumns = ["recordId"],childColumns = ["recordId"]
                )
        ]
)
data class ProjectRecordCrossRef(

        val projectId: Int,@ColumnInfo(index = true)
        val recordId: Int,val quantity: Int
)

一个 POJO 类

data class ProjectWithRecords(
        @Embedded
        val project: Project,@Relation(
                parentColumn = "projectId",entityColumn = "recordId",associateBy = Junction(ProjectRecordCrossRef::class)
        )
        val records: MutableList<Record>,@Relation(
                entity = ProjectRecordCrossRef::class,parentColumn = "projectId",entityColumn = "quantity"
        )
        val quantities: MutableList<Int> = arraylistof()
)

我还有一个Dao课

@Dao
interface CrossRefDao {

    @Transaction
    @Query("SELECT * FROM projects WHERE projectId = :projectId")
    fun getProjectWithRecords(projectId: Int): LiveData<ProjectWithRecords>

    @Query("SELECT * FROM cross_ref WHERE projectId =:projectId")
    suspend fun getAllByProjectId(projectId: Int) : List<ProjectRecordCrossRef>

    @Query("SELECT * FROM cross_ref")
    suspend fun getAllCrosses(): List<ProjectRecordCrossRef>

    @Query("SELECT * FROM cross_ref WHERE projectId =:projectId AND recordId =:recordId")
    suspend fun getAllByProjectAndRecordIds(projectId: Int,recordId: Int) : List<ProjectRecordCrossRef>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(crossRef: ProjectRecordCrossRef)

    @Delete
    suspend fun delete(crossRefs: List<ProjectRecordCrossRef>)
}

问题是:我无法从 POJO 中的 Dao 获取数量

那么,如何从交叉引用中获取第三方值列表?

ProjectWithRecords 有 项目, 记录清单, 记录数量列表。

也许我应该换一种方式?

解决方法

ProjectWithRecords POJO 中,关系将(应该)检索一个 ProjectRecordCrossRef 对象,以便您可以获取一个列表,然后获取数量。

然而,另外你说的是项目和数量之间的关系(可能很幸运能得到匹配,但你只会得到与 projectId 匹配的数量)。

考虑以下事项:-

data class ProjectWithRecords(
    @Embedded
    val project: Project,@Relation(
        parentColumn = "projectId",entityColumn = "recordId",associateBy = Junction(ProjectRecordCrossRef::class)
    )
    val records: MutableList<Record>,@Relation(
        entity = ProjectRecordCrossRef::class,parentColumn = "projectId",entityColumn = "projectId" //<<<<<
    )
    //val quantities: MutableList<Int> = arrayListOf()
    val projectRecordCrossRef: List<ProjectRecordCrossRef>
)

利用您提供的代码(为方便起见略作修改)、修改后的 POJO(如上)和 Activity 中的以下测试/演示:-

    dao = db.getCrossRefDao()

    val p1Id = dao.insert(Project(0,"Project1","blah for project1","2021-01-01",111))
    val p2Id = dao.insert(Project(0,"Project2","blah for project2","2021-03-03",222))
    val r1Id = dao.insert(Record(0,"Record1","detail for record 1",10))
    val r2Id = dao.insert(Record(0,"Record2","details for record 2",20))
    val r3Id = dao.insert(Record(0,"Record3","details for record 3",30))
    val r4Id = dao.insert(Record(0,"Record4","details for record 4",40))
    dao.insert(ProjectRecordCrossRef(p1Id,r3Id,10000))
    dao.insert(ProjectRecordCrossRef(p1Id,r2Id,20000))
    dao.insert(ProjectRecordCrossRef(p1Id,r1Id,30000))
    dao.insert(ProjectRecordCrossRef(p2Id,40000))
    dao.insert(ProjectRecordCrossRef(p2Id,r4Id,50000))

    val pwr = dao.getProjectWithRecords(1)
    Log.d("PRINFO","Project is ${pwr.project.title}")
    for (prcr: ProjectRecordCrossRef in pwr.projectRecordCrossRef)
        Log.d("PRINFO","\tQuantity is ${prcr.quantity}" )

运行时日志中的结果是:-

D/PRINFO: Project is Project1
D/PRINFO:   Quantity is 30000
D/PRINFO:   Quantity is 20000
D/PRINFO:   Quantity is 10000