可以说,一个任务可以由许多其他任务(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 也是错误的
带有任务数据类的正确任务如何?
数据类似乎是错误的,所以 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:-