问题描述
我已经在User,Property和这两个项目UserPropertyJunction的联结表之间创建了一个关系,可以在下图中将其可视化为关联关系
UserEntity,而不是customers
@Entity(tableName = "user")
data class UserEntity(
@PrimaryKey
val userId: Long,val firstName: String,val lastName: String,val email: String,val password: String
)
属性,而不是products
@Entity(
tableName = "property",primaryKeys = ["id"]
)
data class Property(
val id: Int,val update: Int,val categoryId: Int,val title: String,val subject: String,val type: String,val typeId: Int
}
并连接表而不是product_helper
@Entity(
tableName = "user_property_junction",primaryKeys = ["userAccountId","propertyId"],// Foreign Keys
foreignKeys = [
ForeignKey(
entity = User::class,parentColumns = ["userId"],childColumns = ["userAccountId"],onDelete = ForeignKey.NO_ACTION
),ForeignKey(
entity = Property::class,parentColumns = ["id"],childColumns = ["propertyId"],onDelete = ForeignKey.NO_ACTION
)
]
)
data class UserPropertyJunction(
val userAccountId: Long,val propertyId: Int
)
并使用
创建关系类data class UserWithFavorites(
@Embedded
val user: User,@Relation(
parentColumn = "userId",entity = Property::class,entityColumn = "id",associateBy = Junction(
value = UserPropertyJunction::class,parentColumn = "userAccountId",entityColumn = "propertyId"
)
)
val propertyList: List<Property>
)
为此,我们签出了解决方案in this link,该解决方案向联结添加了其他字段,在我的示例中,添加了displayCount
和favorite
属性
data class UserPropertyJunction(
val userAccountId: Long,val propertyId: Int,val displayCount:Int=0,val favorite:Boolean=false
)
据我所知,我的第一个问题是对联结表或关联表没有太多的经验,它们仅存储应与之关联的表的外键,可以在联结表中添加值字段吗?
如果它不是很优雅或不是首选的方式,我应该添加另一个与联结表有关系的表,例如
data class PropertyStatus(
val userAccountId: Long,val favorite:Boolean=false
)
并关联他们?
当从用户属性和属性状态两者中检索数据时,我应该手动从中获取数据
data class UserWithProperties(
@Embedded
val user: User,entityColumn = "propertyId"
)
)
val propertyList: List<Property>
)
并根据您对第一个问题的答案从状态表或联结表中使用SELECT获取
或者可以通过UserWithProperties
或@Embedded
@Relation
添加另一个关系解决方法
据我所知,不幸的是,没有开箱即用的方法,仅用Room的工具(@ Relation,@ Embedded,@ Junction)就可以解决用例。
据我所知,我的第一个问题是对联结表或关联表没有太多的经验,它们仅存储应与之关联的表的外键,可以在联结表中添加值字段吗?
问题是@Junction在使用中有一些限制-它仅有助于将两个表与保存在第三个(连接)表中的值绑定在一起。但是@Relation-with-@Junction API
不支持从此联结表中获取要包含在结果类中的任何字段(这些外键仅用于绑定)。因此,从技术上讲,您可以向联结表中添加一些字段(似乎是保留这些值的最合适的地方),但是实际上,您无法使用@Junction获得这些字段。
也许可以使用一些破解方式,但是我的猜测-您必须使用SQL连接实现自己的方法,并通过循环传递结果以形成所需的结果(类似于在您在帖子中提到的链接)。
为简化起见,您可以按照您的建议真正描述实体连接表(但完全不要使用@Junction):
data class UserPropertyJunction(
val userAccountId: Long,val propertyId: Int,val displayCount:Int=0,val favorite:Boolean=false
)
,然后添加辅助类(不是实体)并将其用作查询结果:
data class UserWithFavorites(
val displayCount:Int,val favorite:Boolean,@Relation(
parentColumn = "userAccountId",entityColumn = "userId"
)
val user: UserEntity,@Relation(
parentColumn = "propertyId",entityColumn = "id"
)
val property: Property,)
当然,这不是您想要的,但至少您可以处理,它是开箱即用的,您可以将其与LiveData / Flow / RxJava一起使用(例如,在获得此权限之后,您可以尝试使用一些转换运算符以某种方式将其更改为所需的格式)
更新(用于简化版)
如果结果中不需要用户,而只想按userId进行过滤,则辅助类可能如下:
data class PropertiesWithFavorites(
val displayCount:Int,val favourite:Boolean,val propertyId: Long,entityColumn = "id"
)
val property: Property
)
和道方法:
@Query("SELECT * FROM user_property_junction as j where j.userAccountId =:userId")
fun getPropertiesByUser(userId: Long): List<PropertiesWithFavorites>