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

时间:2015-06-01 06:53:35

标签: scala slick slick-3.0

基本上,大约一年前,对于光滑的2.x(scala slick one-to-many collections)也提出了同样的问题。我想知道是否有任何进展与反应光滑的发布。

比方说我们有三张桌子。 librarybooklibrary_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 => ??? )
在这种情况下,

results的类型为Seq[(Library, Book)]。如何更改查询以获取类型Seq[(Library, Seq[Book])]的结果?编写此类查询的“光滑方式”是什么?

2 个答案:

答案 0 :(得分:7)

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

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)

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

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

答案 1 :(得分:0)

对于你要映射到的内容,db.run返回一个Future(of something),一个Future [Seq [(Library,Seq [Book])]]。在未来的映射中,您可以访问Seq,并且可以将其转换为其他内容以获得新的Future。