我有下面的数据结构工作包括一个工人列表和海报列表海报有一个工人。
我能够获得嵌入到Job对象中的工人和海报列表;但我无法将单个工作线程放入海报对象。
我尝试过使用关系和实体,但遇到了实体不能包含关系的问题,为了能够包含关系,它必须是实体。这意味着当我尝试使用PosterWithWorker类将Worker关系添加到Poster对象时,JobsWithWorkersAndPosters会拒绝它,因为它不是实体,我不能使它成为实体。
我尝试使用外键将worker表Map到poster表。
@Entity
(tableName = "poster")
data class Poster (
@PrimaryKey val poster_id: Int,
val job_id: Int,
val qr_code: String,
var status: Int,
@ColumnInfo(name = "worker_id", index = true)
val worker_id: Int,
val longitude: Double,
val latitude: Double)
@Entity(tableName = "worker",
foreignKeys = [
androidx.room.ForeignKey(
entity = Poster::class,
parentColumns = ["poster_id"],
childColumns = ["worker_id"],
onDelete = CASCADE,
onUpdate = CASCADE
)])
data class Worker(
@PrimaryKey
@ColumnInfo(name = "worker_id")
val worker_id: Int,
val workerName: String,
)
data class PosterWithWorker(
@Embedded val poster: Poster,
@Relation(
parentColumn = "poster_id",
entityColumn = "worker_id"
)
val worker: Worker
)
data class JobWithPostersAndWorkers(
@Embedded val job: Job,
@Relation(
parentColumn = "job_id",
entityColumn = "worker_id",
associateBy = Junction(JobWorkerCrossRef::class)
)
val workers: List<Worker>,
@Relation(entity=Poster::class, parentColumn = "job_id", entityColumn = "job_id")
val poster: List<PosterWithWorker>
)
data class PosterWithWorker(
@Embedded val poster: Poster,
@Relation(
parentColumn = "poster_id",
entityColumn = "worker_id"
)
val worker: Worker
)
我遵循这个Android room - 3 one-to-many relationship示例,并尝试遵循相同的嵌套模式。
我尝试了不同的变体,得到了不同的错误。
我的第一个问题是,这是否可以不使用外键来完成,然后我做错了什么。
1条答案
按热度按时间aiqt4smr1#
我的第一个问题是,这是否可以不使用外键来完成,然后我做错了什么。
是,参考答案包括:
foreignKeys是可选的,但可以强制并帮助维护参照完整性。在外键中,onDelete和onUpdate是可选的
在SQLite中,一个外键是Room的 Package 器,它是一个约束(一个规则),其中FK约束所应用到的列中的值(子列)必须是一个存在于被引用的列中的值(父列)。即,称为引用完整性。另一种思考方式是外键约束禁止孤儿。
在您的场景中(根据注解 ,我想在poster类中添加一个worker字段。每个poster只有一个worker。)
使用:-
您实际上是在说worker_id列必须是Poster表的poster_id列中的一个现有值,从而将worker的数量限制为Poster的数量。
我相信你想要的是:
例如,海报包括对单个工人(必须存在)的引用。即海报是(海报是)工人的孩子。工人可以有许多孩子(海报)。
重新
作业包括工人列表和海报列表,海报只有一个工人。
这与下面的评论相矛盾
事实上,这里还有另一个困惑,理想的海报不需要工人。
你还评论
我尝试了您的解决方案,但遇到FOREIGN KEY约束失败(代码787 SQLITE_CONSTRAINT_FOREIGNKEY)错误。
这是因为在父表中没有空行,因此如果您试图引用无海报,则规则将被破坏。
定义外键时,定义FK的列将是子列,引用的列将是父列。
假设这里有一个解决方案,它允许一个作业有许多(0-百万)工作者,并且同一个工作者可以是许多作业的一部分。这是一个多-多关系。它也适合尴尬的海报工作者,但也适合引用完整性(外键)。
所以你可以从三个核心表格开始,工作,工人和海报。前两个是独立于其他表格的。
作为一个海报必须有一个工作作为它的父和一个工作可以有许多海报(即海报列表)。这是一个1(工作)到许多(海报)。一个外键可以用来加强引用完整性。即海报不能存在没有一个父。所以:-
接下来是Workers per Job的列表,假设一个Worker可以是多个工作的Worker,因此存在一个many0many关系,因此存在一个中间/交叉引用/Map/关联....表。
因此:
在此阶段,海报的工作者已被省略。因此,可能出现无工作者的情况。然而,为了允许工作者,可以使用Map表(0-多个),但需要限制为单个工作者(如果有)。这可以通过仅在海报列上设置主键而不是在两列的组合上设置主键来实现。因此:-
若要支持海报包含此0或1工人,则:-
最后,为了迎合工作与它的工人和它的海报与工人或不那么:
演示一些DAO函数:
实际演示以下内容:-