我有一个模型结构如下:
Group -> Many Parties -> Many Participants
在一个API调用中,我需要获得具有各方和它的参与者的单个组。
整个结构建立在4个表上:
- 组
- 方
- party_participant
很自然地,对于SQL来说,这是一个非常直接的连接,它将所有这些组合在一起。这正是我想用slick做的。Mu方法的dao类是这样的:
def findOneByKeyAndAccountIdWithPartiesAndParticipants(key: UUID, accountId: Int): Future[Option[JourneyGroup]] = {
val joins = JourneyGroups.groups join
Parties.parties on (_.id === _.journeyGroupId) joinLeft
PartiesParticipants.relations on (_._2.id === _.partyId) joinLeft
Participants.participants on (_._2.map(_.participantId) === _.id)
val query = joins.filter(_._1._1._1.accountId === accountId).filter(_._1._1._1.key === key)
val q = for {
(((journeyGroup, party), partyParticipant), participant) <- query
} yield (journeyGroup, party, participant)
val result = db.run(q.result)
result ????
}
这里的问题是,result
是Future[Seq[(JourneyGroup, Party, Participant)]]
的类型
然而,我真正需要的是Future[Option[JourneyGroup]]
注意:JourneyGroup
和Party
的case类为它们的子类定义了序列:
case class Party(id: Option[Int] = None,
partyType: Parties.Type.Value,
journeyGroupId: Int,
accountId: Int,
participants: Seq[Participant] = Seq.empty[Participant])
和
case class JourneyGroup(id: Option[Int] = None,
key: UUID,
name: String,
data: Option[JsValue],
accountId: Int,
parties: Seq[Party] = Seq.empty[Party])
所以他们都可以拥有后代。
转换为我需要的结果的正确方法是什么?还是我完全走错方向了?
同样,这个说法是正确的吗?Participants.participants on (_._2.map(_.participantId) === _.id)
?
我最终做了这样的事情:
journeyGroupDao.findOneByKeyAndAccountIdWithPartiesAndParticipants(key, account.id.get) map { data =>
val groupedByJourneyGroup = data.groupBy(_._1)
groupedByJourneyGroup.map { case (group, rows) =>
val parties = rows.map(_._2).distinct map { party =>
val participants = rows.filter(r => r._2.id == party.id).flatMap(_._3)
party.copy(participants = participants)
}
group.copy(parties = parties)
}.headOption
}
,其中DAO方法的签名是:
def findOneByKeyAndAccountIdWithPartiesAndParticipants(key: UUID, accountId: Int): Future[Seq[(JourneyGroup, Party, Option[Participant])]]