具有 2 个实体的数据 class 混淆了列
Data class with 2 entites confuses columns
我在 Android 应用程序的房间数据库中有两个实体。
这个概念是每个站点都有很多组。
@Entity(tableName = "sites")
data class Site(
@ColumnInfo(name = "server_id")
var serverId: Long,
@PrimaryKey
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
@Entity(tableName = "groups")
data class Group(
@ColumnInfo(name = "server_id")
val serverId: Long,
@PrimaryKey
@ColumnInfo(name = "group_id")
var groupId: Int,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
所以我想给定一个 siteId 和一个 groupId,两个从数据库中获取一个名为 SiteWithGroup 的 POJO
这是
data class SiteWithGroup(
@Embedded
val site: Site,
@Relation(parentColumn = "site_id", entityColumn = "site_id", entity = Group::class)
val group: Group
)
我创建了一个 MediatorLiveData,它观察 siteId、groupId,当它同时拥有这两个时 returns 来自 db 的查询
private val siteGroupPair = MediatorLiveData<Pair<Int?, Int?>>().apply {
addSource(siteId) {
value = Pair(it, groupId.value)
}
addSource(groupId) {
value = Pair(siteId.value, it)
}
}
override val siteGroup: LiveData<SiteWithGroup>
get() = Transformations.switchMap(siteGroupPair) {
it?.let { pair ->
if (pair.first != null && pair.second != null)
sitesRepository.siteWithGroup(pair.first!!, pair.second!!)
else null
}
}
//Dao query
@Query("""Select * from groups
inner join sites on groups.site_id = :siteId
where sites.site_id = :siteId and groups.group_id = :groupId
""")
fun getByIdWithGroups(siteId: Int, groupId: Int): LiveData<SiteWithGroup>
如果我们假设 siteId、groupId = 1、1 和我在我的数据库中有以下条目
Group entity
serverId, groupId, siteId, description
1 1 1 "Group1 description"
1 2 1 "Group2 description"
________________________________________________
Site entity
serverId, siteId, description
1 1 "Site1 description"
我们期望结果是
SiteWithGroup(
site=Site(serverId=1, siteId=1, description=Site1 description),
group=Group(serverId=1, groupId=2, siteId=1, description=Group2 description)
)
但我们却得到了这个
SiteWithGroup(
site=Site(serverId=1, siteId=1, description= !!!<<Group1 description>>!!!),
group=Group(serverId=1, groupId=<<2>>, siteId=1, description= <<Group2 description>>)
)
站点实体得到的组描述是错误的!!
似乎在 all.How 没有应用组约束,这是发生了吗?我该如何解决?
谢谢
然而在我的 UI 结果是
您试图将 join
与 @Relation
混合使用,这会导致不可预知的结果。
请记住,使用 @Relation
Room,第一步应用您给定的查询以从主要实体站点 (select * from sites ...
) 获取数据,然后在第二步 - 启动另一个查询附加第二个实体的组数据(大约 select * from groups where siteId IN <List of siteIds gotten after step1>
)。因此,在第二个查询中, group_id
不再有任何条件(并且您无法选择在那里设置此条件,因为查询是自动生成的)并且可能会选择任何组(测试用例中的两个中的任何一个) .
我想修复你可以替换数据中的实体 Site
和 Group
class:
data class SiteWithGroup(
@Embedded
val group: Group,
@Relation(parentColumn = "site_id", entityColumn = "site_id")
val site: Site
)
dao 查询不应该包含任何 Join(它可以但是它真的没用):
@Transaction
@Query("Select * from groups where site_id = :siteId and group_id = :groupId")
fun getByIdWithGroups(siteId: Int, groupId: Int): LiveData<SiteWithGroup>
我在 Android 应用程序的房间数据库中有两个实体。 这个概念是每个站点都有很多组。
@Entity(tableName = "sites")
data class Site(
@ColumnInfo(name = "server_id")
var serverId: Long,
@PrimaryKey
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
@Entity(tableName = "groups")
data class Group(
@ColumnInfo(name = "server_id")
val serverId: Long,
@PrimaryKey
@ColumnInfo(name = "group_id")
var groupId: Int,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
所以我想给定一个 siteId 和一个 groupId,两个从数据库中获取一个名为 SiteWithGroup 的 POJO 这是
data class SiteWithGroup(
@Embedded
val site: Site,
@Relation(parentColumn = "site_id", entityColumn = "site_id", entity = Group::class)
val group: Group
)
我创建了一个 MediatorLiveData,它观察 siteId、groupId,当它同时拥有这两个时 returns 来自 db 的查询
private val siteGroupPair = MediatorLiveData<Pair<Int?, Int?>>().apply {
addSource(siteId) {
value = Pair(it, groupId.value)
}
addSource(groupId) {
value = Pair(siteId.value, it)
}
}
override val siteGroup: LiveData<SiteWithGroup>
get() = Transformations.switchMap(siteGroupPair) {
it?.let { pair ->
if (pair.first != null && pair.second != null)
sitesRepository.siteWithGroup(pair.first!!, pair.second!!)
else null
}
}
//Dao query
@Query("""Select * from groups
inner join sites on groups.site_id = :siteId
where sites.site_id = :siteId and groups.group_id = :groupId
""")
fun getByIdWithGroups(siteId: Int, groupId: Int): LiveData<SiteWithGroup>
如果我们假设 siteId、groupId = 1、1 和我在我的数据库中有以下条目
Group entity
serverId, groupId, siteId, description
1 1 1 "Group1 description"
1 2 1 "Group2 description"
________________________________________________
Site entity
serverId, siteId, description
1 1 "Site1 description"
我们期望结果是
SiteWithGroup(
site=Site(serverId=1, siteId=1, description=Site1 description),
group=Group(serverId=1, groupId=2, siteId=1, description=Group2 description)
)
但我们却得到了这个
SiteWithGroup(
site=Site(serverId=1, siteId=1, description= !!!<<Group1 description>>!!!),
group=Group(serverId=1, groupId=<<2>>, siteId=1, description= <<Group2 description>>)
)
站点实体得到的组描述是错误的!! 似乎在 all.How 没有应用组约束,这是发生了吗?我该如何解决? 谢谢
然而在我的 UI 结果是
您试图将 join
与 @Relation
混合使用,这会导致不可预知的结果。
请记住,使用 @Relation
Room,第一步应用您给定的查询以从主要实体站点 (select * from sites ...
) 获取数据,然后在第二步 - 启动另一个查询附加第二个实体的组数据(大约 select * from groups where siteId IN <List of siteIds gotten after step1>
)。因此,在第二个查询中, group_id
不再有任何条件(并且您无法选择在那里设置此条件,因为查询是自动生成的)并且可能会选择任何组(测试用例中的两个中的任何一个) .
我想修复你可以替换数据中的实体 Site
和 Group
class:
data class SiteWithGroup(
@Embedded
val group: Group,
@Relation(parentColumn = "site_id", entityColumn = "site_id")
val site: Site
)
dao 查询不应该包含任何 Join(它可以但是它真的没用):
@Transaction
@Query("Select * from groups where site_id = :siteId and group_id = :groupId")
fun getByIdWithGroups(siteId: Int, groupId: Int): LiveData<SiteWithGroup>