我有以下结构来定义与朋友的会议。首先我有我的
Friend
实体
@Entity(tableName = Friend.TABLE_NAME)
data class Friend(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
val alias: String? = null
) {
companion object {
const val TABLE_NAME = "friends"
}
}
还有我的会议实体
@Entity(tableName = Meeting.TABLE_NAME)
data class Meeting(
@PrimaryKey(autoGenerate = true)
val id: Int?,
val friendId: Int?,
val date: LocalDateTime?
) {
companion object {
const val TABLE_NAME = "meetings"
}
}
然后是一个帮助器类来关联它们:
data class FriendMeetings(
@Embedded
val friend: Friend= Friend(),
@Relation(
parentColumn = "id",
entityColumn = "friendId"
)
val meetings: List<Meeting>
)
还为
LocalDateTime
字段定义了类型转换器
class AppConverters {
@TypeConverter
fun fromLocalDateTime(date: LocalDateTime?): Long? =
date?.toMillis()
@TypeConverter
fun toLocalDateTime(millisSinceEpoch: Long?): LocalDateTime? =
if (millisSinceEpoch == null) {
null
} else LocalDateTime.ofInstant(
Instant.ofEpochMilli(millisSinceEpoch),
ZoneId.systemDefault()
)
}
当我在 dao 中询问所有朋友的列表时,它的效果非常好
@Query("SELECT * FROM friends ORDER BY id")
fun getAll(): List<FriendMeetings>
如果我在 dao 中要求在给定的日期与朋友会面,它会很有效
@Query("SELECT * FROM friends INNER JOIN meetings ON friends.id = meetings.friendId WHERE friends.id = :id AND meetings.date BETWEEN :startOfDay AND :endOfDay")
fun getMeetingsWithFriendBetweenDates(id: Long, startOfDay: Long, endOfDay: Long): FriendMeetings?
但是如果我尝试在给定日期举行所有会议,结果将不正确
@Query("SELECT * FROM friends INNER JOIN meetings ON friends.id = meetings.friendId WHERE meetings.date BETWEEN :startOfDay AND :endOfDay")
fun getMeetingsBetweenDates(startOfDay: Long, endOfDay: Long): List<FriendMeetings>?
在这种情况下,我得到了正确的朋友数量,但在会议正确的情况下,朋友数据会一直重复。我只是想,由于一天的会议不会很多,我可以加载会议,然后为每个会议加载朋友,但似乎有点令人讨厌,但我不知道这里出了什么问题
当 Room 对 @Relation 执行操作时,它将以任意顺序返回相应父级的所有子级。也就是说
@Query
仅用于确定父级,底层 @Relations
是由不带参数的底层查询构建的。
您需要做的是绕过/覆盖 Room 的便利处理。这可以通过使用具有控制两个因素的主体的函数来实现:-
所以我相信您对所有
Friend
但在提供的开始和结束日期之间有 Meeting
的解决方案可能是在 @Dao
接口或抽象类中具有以下功能:-
@Query("SELECT * FROM friends ORDER BY id")
fun getAllFriends(): List<Friend>
@Query("SELECT * FROM meetings WHERE meetings.friendId=:friendId AND meetings.date BETWEEN :startOfDay: Long AND :endOfDay")
fun getMeetingsForAFriendBetweenDates(friendId: Int?, startOfDay: Long, endOfDay: Long): List<Meeting>
@Transaction
@Query("")
fun getFriendWithMeetingsBetweenDates(id: Long, startOfDay: Long, endOfDay: Long): List<FriendMeetings> {
val rv = ArrayList<FriendMeetings>()
for(f in getAllFriends()) {
val meetings = getMeetingsForAFriendBetweenDates(f.id, startOfDay, endOfDay)
rv.add(FriendMeetings(f,meetings))
}
return rv
}
@Query("")
是让Room将@Transaction
应用到函数