SLICK 3.0多对多查询,将连接作为可迭代 [英] Slick 3.0 many-to-many query with the join as an iterable

查看:0
本文介绍了SLICK 3.0多对多查询,将连接作为可迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用SLICK 3.0创建了一个多对多集合,但我正在努力以我想要的方式检索数据。

事件和利益之间存在多对多的关系。以下是我的表格:

case class EventDao(title: String,
                    id: Option[Int] = None)


class EventsTable(tag: Tag)
  extends Table[EventDao](tag, "events") {

  def id = column[Int]("event_id", O.PrimaryKey, O.AutoInc)
  def title = column[String]("title")

  def * = (
    title,
    id.?) <> (EventDao.tupled, EventDao.unapply)

  def interests = EventInterestQueries.query.filter(_.eventId === id)
    .flatMap(_.interestFk)
}


object EventQueries {

  lazy val query = TableQuery[EventsTable]

  val findById = Compiled { k: Rep[Int] =>
    query.filter(_.id === k)
  }
}

以下是EventsInterest:

case class EventInterestDao(event: Int, interest: Int)


class EventsInterestsTable(tag: Tag)
  extends Table[EventInterestDao](tag, "events_interests") {

  def eventId = column[Int]("event_id")
  def interestId = column[Int]("interest_id")

  def * = (
    eventId,
    interestId) <> (EventInterestDao.tupled, EventInterestDao.unapply)

  def eventFk = foreignKey("event_fk", eventId, EventQueries.query)(e => e.id)
  def interestFk = foreignKey("interest_fk", interestId, InterestQueries.query)(i => i.id)
}


object EventInterestQueries {
  lazy val query = TableQuery[EventsInterestsTable]
}

最终兴趣:

case class InterestDao(name: String,
                       id: Option[Int] = None)

class InterestsTable(tag: Tag)
  extends Table[InterestDao](tag, "interests") {

  def id = column[Int]("interest_id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def name_idx = index("idx_name", name, unique = true)

  def * = (
    name,
    id.?) <> (InterestDao.tupled, InterestDao.unapply)

  def events = EventInterestQueries.query.filter(_.interestId === id)
    .flatMap(_.eventFk)
}


object InterestQueries {

  lazy val query = TableQuery[InterestsTable]

  val findById = Compiled { k: Rep[Int] =>
    query.filter(_.id === k)
  }
}

我可以使用以下内容查询和检索(vent.name,interest)的元组:

val eventInterestQuery = for {
  event <- EventQueries.query
  interest <- event.interests
} yield (event.title, interest.name)

Await.result(db.run(eventInterestQuery.result).map(println), Duration.Inf)

这就是我目前所拥有的。

我想要的是能够填充Case类,如:

case class EventDao(title: String,
                interests: Seq[InterestDao],
                id: Option[Int] = None)

问题是,如果我像这样更新我的Case类,它会破坏EventsTable中的def *投影。此外,我将不得不将EventsTable.interests过滤器重命名为类似EventsTable.interestIds的名称,这有点难看,但如果需要的话,我可以接受。

此外,我找不到一种方法来编写生成(event.name, Seq(interest.name))for查询。无论如何,这只是我能够生成(EventDao, Seq(InterestDao))元组的垫脚石,而这正是我真正想要返回的。

有人知道我如何实现这些目标吗?我还希望能够‘获取’一定数量的兴趣,因此对于某些查询,将返回全部,但对于其他查询,将仅返回前3个兴趣。

推荐答案

所以在阅读this page并在邮件列表上聊天后,我终于让它正常工作了:

val eventInterestQuery = for {
  event <- EventQueries.query
  interest <- event.interests
} yield (event, interest)

Await.result(db.run(eventInterestQuery.result
  // convert the interests to a sequence.
  .map {
  _.groupBy(_._1)
    .map {
      case (k,v) => (k, v.map(_._2))
  }.toSeq
}
), Duration.Inf)

这篇关于SLICK 3.0多对多查询,将连接作为可迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆