如何正确地建立一个基于多层次连接的对象图



我有一个模型结构如下:

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 ????
  }

这里的问题是,resultFuture[Seq[(JourneyGroup, Party, Participant)]]的类型

然而,我真正需要的是Future[Option[JourneyGroup]]

注意:JourneyGroupParty的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])]]

最新更新