如何用Room
表示“多对多”关系?我的列名也是一样的。
例如,我有Guest
和Reservation
。Reservation
可以有多个Guest
,一个Guest
可以是许多预留的一部分。
以下是我的实体定义:
@Entity data class Reservation(
@PrimaryKey val id: Long,
val table: String,
val guests: List<Guest>
)
@Entity data class Guest(
@PrimaryKey val id: Long,
val name: String,
val email: String
)
在查看文档时,我遇到了@Relation
。不过,我发现它真的很令人困惑。
根据这一点,我想创建一个POJO,并在那里添加关系。因此,在我的示例中,我执行了以下操作:
data class ReservationForGuest(
@Embedded val reservation: Reservation,
@Relation(
parentColumn = "reservation.id",
entityColumn = "id",
entity = Guest::class
) val guestList: List<Guest>
)
在上面的代码中,我得到了编译器错误:
> Cannot figure out how to read this field from a cursor.
我找不到@Relation
的工作样本。
发布于 2017-06-08 14:42:22
我也遇到过类似的问题。这是我的解决方案。
您可以使用一个额外的实体(ReservationGuest
)来保持Guest
和Reservation
之间的关系。
@Entity data class Guest(
@PrimaryKey val id: Long,
val name: String,
val email: String
)
@Entity data class Reservation(
@PrimaryKey val id: Long,
val table: String
)
@Entity data class ReservationGuest(
@PrimaryKey(autoGenerate = true) val id: Long,
val reservationId: Long,
val guestId: Long
)
您可以通过他们的guestId
列表(而不是来宾对象)获得预订。
data class ReservationWithGuests(
@Embedded val reservation:Reservation,
@Relation(
parentColumn = "id",
entityColumn = "reservationId",
entity = ReservationGuest::class,
projection = "guestId"
) val guestIdList: List<Long>
)
您还可以使用客户的预订列表(而不是reservationId
对象)来获取客户
data class GuestWithReservations(
@Embedded val guest:Guest,
@Relation(
parentColumn = "id",
entityColumn = "guestId",
entity = ReservationGuest::class,
projection = "reservationId"
) val reservationIdList: List<Long>
)
由于可以获得guestId
和reservationId
,因此可以使用它们查询Reservation
和Guest
实体。
如果我找到一种简单的方法来获取预订和访客对象列表,而不是它们的ids,我会更新我的答案。
发布于 2019-10-17 12:09:24
通过在房间中介绍Junction,您可以轻松处理多对多关系。
正如@Devrim所说,您可以使用一个额外的实体(ReservationGuest)来保持客户和预订之间的关系(也称为关联表、连接表或连接表)。
@Entity
data class Guest(
@PrimaryKey
val gId: Long,
val name: String,
val email: String
)
@Entity
data class Reservation(
@PrimaryKey
val rId: Long,
val table: String
)
@Entity(
primaryKeys = ["reservationId", "guestId"]
)
data class ReservationGuest(
val reservationId: Long,
val guestId: Long
)
现在,您可以使用此模型与客人进行预订:
data class ReservationWithGuests (
@Embedded
val reservation: Reservation,
@Relation(
parentColumn = "rId",
entity = Guest::class,
entityColumn = "gId",
associateBy = Junction(
value = ReservationGuest::class,
parentColumn = "reservationId",
entityColumn = "guestId"
)
)
val guests: List<Guest>
)
您也可以通过客人的预订列表获得他们的预订。
data class GuestWithReservations (
@Embedded
val guest: Guest,
@Relation(
parentColumn = "gId",
entity = Reservation::class,
entityColumn = "rId",
associateBy = Junction(
value = ReservationGuest::class,
parentColumn = "guestId",
entityColumn = "reservationId"
)
)
val reservations: List<Reservation>
)
现在您可以在数据库中查询结果,如下所示:
@Dao
interface GuestReservationDao {
@Query("SELECT * FROM Reservation")
fun getReservationWithGuests(): LiveData<List<ReservationWithGuests>>
@Query("SELECT * FROM Guest")
fun getGuestWithReservations(): LiveData<List<GuestWithReservations>>
}
发布于 2018-05-27 17:31:32
实际上还有一种获取Guest
列表的可能性,而不仅仅是@Devrim答案中的id。
首先定义表示Guest
和Reservation
之间连接的类。
@Entity(primaryKeys = ["reservationId", "guestId"],
foreignKeys = [
ForeignKey(entity = Reservation::class,
parentColumns = ["id"],
childColumns = ["reservationId"]),
ForeignKey(entity = Guest::class,
parentColumns = ["id"],
childColumns = ["guestId"])
])
data class ReservationGuestJoin(
val reservationId: Long,
val guestId: Long
)
每次要插入新的Reservation
时,都必须插入ReservationGuestJoin
对象以满足外键约束。现在,如果你想得到Guest
列表,你可以使用SQL query的强大功能:
@Dao
interface ReservationGuestJoinDao {
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
@Query("""
SELECT * FROM guest INNER JOIN reservationGuestJoin ON
guest.id = reservationGuestJoin.guestId WHERE
reservationGuestJoin.reservationId = :reservationId
""")
fun getGuestsWithReservationId(reservationId: Long): List<Guest>
}
要查看更多详细信息,请访问this blog。
https://stackoverflow.com/questions/44361824
复制相似问题