首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在列名相同的情况下,如何表示Android Room的多对多关系?

在列名相同的情况下,如何表示Android Room的多对多关系?
EN

Stack Overflow用户
提问于 2017-06-05 12:47:42
回答 5查看 31.2K关注 0票数 60

如何用Room表示“多对多”关系?我的列名也是一样的。

例如,我有GuestReservationReservation可以有多个Guest,一个Guest可以是许多预留的一部分。

以下是我的实体定义:

代码语言:javascript
复制
@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,并在那里添加关系。因此,在我的示例中,我执行了以下操作:

代码语言:javascript
复制
data class ReservationForGuest(
    @Embedded val reservation: Reservation,
    @Relation(
        parentColumn = "reservation.id", 
        entityColumn = "id", 
        entity = Guest::class
    ) val guestList: List<Guest>
)

在上面的代码中,我得到了编译器错误:

代码语言:javascript
复制
> Cannot figure out how to read this field from a cursor.

我找不到@Relation的工作样本。

EN

回答 5

Stack Overflow用户

发布于 2017-06-08 14:42:22

我也遇到过类似的问题。这是我的解决方案。

您可以使用一个额外的实体(ReservationGuest)来保持GuestReservation之间的关系。

代码语言:javascript
复制
@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列表(而不是来宾对象)获得预订。

代码语言:javascript
复制
data class ReservationWithGuests(
    @Embedded val reservation:Reservation,
    @Relation(
        parentColumn = "id",
        entityColumn = "reservationId",
        entity = ReservationGuest::class,
        projection = "guestId"
    ) val guestIdList: List<Long>
)

您还可以使用客户的预订列表(而不是reservationId对象)来获取客户

代码语言:javascript
复制
data class GuestWithReservations(
    @Embedded val guest:Guest,
    @Relation(
        parentColumn = "id",
        entityColumn = "guestId",
        entity = ReservationGuest::class,
        projection = "reservationId"
   ) val reservationIdList: List<Long>
)

由于可以获得guestIdreservationId,因此可以使用它们查询ReservationGuest实体。

如果我找到一种简单的方法来获取预订和访客对象列表,而不是它们的ids,我会更新我的答案。

Similar answer

票数 89
EN

Stack Overflow用户

发布于 2019-10-17 12:09:24

通过在房间中介绍Junction,您可以轻松处理多对多关系。

正如@Devrim所说,您可以使用一个额外的实体(ReservationGuest)来保持客户和预订之间的关系(也称为关联表、连接表或连接表)。

代码语言:javascript
复制
@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
)

现在,您可以使用此模型与客人进行预订:

代码语言:javascript
复制
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>
)

您也可以通过客人的预订列表获得他们的预订。

代码语言:javascript
复制
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>
)

现在您可以在数据库中查询结果,如下所示:

代码语言:javascript
复制
@Dao
interface GuestReservationDao {
  @Query("SELECT * FROM Reservation")
  fun getReservationWithGuests(): LiveData<List<ReservationWithGuests>>

  @Query("SELECT * FROM Guest")
  fun getGuestWithReservations(): LiveData<List<GuestWithReservations>>

}
票数 44
EN

Stack Overflow用户

发布于 2018-05-27 17:31:32

实际上还有一种获取Guest列表的可能性,而不仅仅是@Devrim答案中的id。

首先定义表示GuestReservation之间连接的类。

代码语言:javascript
复制
@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的强大功能:

代码语言:javascript
复制
@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

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44361824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档