Slick 3.0.0:如何查询一对多/多对多关系

Rom*_*man 18 scala slick slick-3.0

基本上同样的问题大约一年前被问到光滑的2.x(scala光滑的一对多收藏).我想知道是否有任何进展与反应浮油的发布.

比方说我们有三张桌子.library,booklibrary_to_book其中一个图书馆有很多书.我想要的是带有书籍的图书馆清单.在scala中,这就像是Seq[(Library, Seq[Book])].我的查询如下:

val q = (for {
  l   <- libraries
  ltb <- libraryToBooks if l.id === ltb.libraryId
  b   <- books if ltb.bookId === b.id
} yield (l, b)
db.run(q.result).map( result => ??? )
Run Code Online (Sandbox Code Playgroud)

results在这种情况下是类型Seq[(Library, Book)].如何更改查询以获取类型的结果Seq[(Library, Seq[Book])]?编写此类查询的"光滑方式"是什么?

pan*_*her 8

IMO您的代码看起来很好.这真的取决于你感觉更可读的东西.或者,您也可以使用join:

val findBooksQuery = libraries
  .join(libraryToBooks).on(_.id === _.libraryId)
  .join(books).on(_.id === _._2.bookId)
  .result

val action = (for {
  booksResult <- findBooksQuery
} yield {
  booksResult.map { row =>
    val (libraryTableRow, libraryToBooksTableRow) = row._1
    val booksTableRow = row._2
    // TODO: Access all data from the rows and construct desired DS
  }
}

db.run(action)
Run Code Online (Sandbox Code Playgroud)

然后,您可以对特定键执行groupBy以获取您要查找的数据结构类型.在这种情况下,它将更加发展,因为它是跨三个表的连接.例如,在查询中添加以下内容:

val findBooksQuery = libraries
  .join(libraryToBooks).on(_.id === _.libraryId)
  .join(books).on(_.id === _._2.bookId)
  // To group by libraries.id
  .groupBy(_._1.id)
  .result
Run Code Online (Sandbox Code Playgroud)