房间中自反多对多关系的任何示例

问题描述 投票:0回答:1

遵循android开发者指南

可以说,一个任务可以由许多其他任务(0,n)组成,一个任务可以由许多其他任务(0,n)组成

因此我们得到了实体及其 id 和名称属性

@Entity(tableName = "tasks")
data class Task(
    @PrimaryKey(autoGenerate = true) val taskId: Long = 0,
    val name: String
)

我们的交叉参考

@Entity(primaryKeys = ["parentTaskId", "childTaskId"])
data class TaskTaskCR(
    val parentTaskId: Long,
    val childTaskId: Long
)

我们的数据类供以后查询

data class TaskWithTasks(
    @Embedded val task: Task,
    @Relation(
        parentColumn = "taskId",
        entityColumn = "childTaskId",
        associateBy = Junction(TaskTaskCR::class)
    )
    val tasks: List<Task>
)

还有我们的 DAO

@Dao
    interface TaskWithTasksDAO {
        @Transaction
        @Query("SELECT * FROM tasks")
        fun getTasksWithTasks(): List<TaskWithTasks>
    }

数据类似乎是错误的,所以 dao 也是错误的

带有任务数据类的正确任务如何?

java kotlin android-jetpack-compose android-room android-jetpack
1个回答
0
投票

数据类似乎是错误的,所以 dao 也是错误的

TaskWithTasks 有问题。换言之,父/子来自交叉引用表中的哪一列?

您需要使用

parentColumn
相应列的
entityColumn
Junction
参数来告诉 Room。

带有任务数据类的正确任务如何?

我相信你应该使用:-

data class TaskWithTasks(
    @Embedded val task: Task,
    @Relation(
        parentColumn = "taskId", /* column in the parent Task */
        entityColumn = "taskId", /* <<<<<CHANGED>>>>> column in the xreferenced child Task */
        associateBy = Junction(
            TaskTaskCR::class,
            parentColumn = "parentTaskId", /* <<<<<ADDED>>>>> column in the cross reference table that references the parent Task */
            entityColumn = "childTaskId" /* <<<<<ADDED>>>>> column in the cross reference table that references the child Task */
        )
    )
    val tasks: List<Task>
)
  • 添加评论来解释

演示

使用:-

@Entity(tableName = "tasks")
data class Task(
    @PrimaryKey(autoGenerate = true) val taskId: Long = 0,
    val name: String
)
/* Our cross reference */

@Entity(primaryKeys = ["parentTaskId", "childTaskId"])
data class TaskTaskCR(
    val parentTaskId: Long,
    val childTaskId: Long
)
/*Our data class for later queries*/

data class TaskWithTasks(
    @Embedded val task: Task,
    @Relation(
        parentColumn = "taskId", /* column in the parent Task */
        entityColumn = "taskId", /* column in the xreferenced child Task */
        associateBy = Junction(
            TaskTaskCR::class,
            parentColumn = "parentTaskId", /* column in the cross reference table that references the parent Task */
            entityColumn = "childTaskId" /* column in the cross reference table that references the child Task */
        )
    )
    val tasks: List<Task>
)
/*And our DAO*/

@Dao
interface TaskWithTasksDAO {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(task: Task): Long
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(taskCR: TaskTaskCR): Long
    @Transaction
    @Query("SELECT * FROM tasks")
    fun getTasksWithTasks(): List<TaskWithTasks>
}

@Database(entities = [Task::class,TaskTaskCR::class], version = 1, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
    abstract fun getTaskWithTaskDao(): TaskWithTasksDAO
    companion object {
        private var instance: TheDatabase?=null
        fun getInstance(context: Context): TheDatabase {
            if (instance==null) {
                instance=Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}

并且:-

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: TaskWithTasksDAO
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        dao = db.getTaskWithTaskDao()
        val t1id = dao.insert(Task(name = "T1"))
        val t2id = dao.insert(Task(name = "T2"))
        val t3id = dao.insert(Task(name = "T3"))
        val t4id = dao.insert(Task(name = "T4"))

        dao.insert(TaskTaskCR(t1id,t1id))
        dao.insert(TaskTaskCR(t1id,t2id))
        dao.insert(TaskTaskCR(t1id,t3id))
        dao.insert(TaskTaskCR(t2id,t4id))
        dao.insert(TaskTaskCR(t3id,t1id))
        dao.insert(TaskTaskCR(t3id,t3id))

        for (ttcr in dao.getTasksWithTasks()) {
            val sb = StringBuilder()
            for (childt in ttcr.tasks) {
                sb.append("\n\t Child Task is ${childt.name} ID is ${childt.taskId}")
            }
            Log.d("DBINFO","Parent Task is ${ttcr.task.name} ID is ${ttcr.task.taskId}. It has ${ttcr.tasks.size} children they are:-${sb}")
        }
    }
}

运行时,日志中的结果包括:-

2024-04-17 15:30:24.451 D/DBINFO: Parent Task is T1 ID is 1. It has 3 children they are:-
         Child Task is T1 ID is 1
         Child Task is T2 ID is 2
         Child Task is T3 ID is 3
2024-04-17 15:30:24.451 D/DBINFO: Parent Task is T2 ID is 2. It has 1 children they are:-
         Child Task is T4 ID is 4
2024-04-17 15:30:24.451 D/DBINFO: Parent Task is T3 ID is 3. It has 2 children they are:-
         Child Task is T1 ID is 1
         Child Task is T3 ID is 3
2024-04-17 15:30:24.451 D/DBINFO: Parent Task is T4 ID is 4. It has 0 children they are:-
  • 即正如预期的那样
© www.soinside.com 2019 - 2024. All rights reserved.