Slick.io - 处理连接表

Slick.io - Handling Joined Tables

我在 Slick (2.1) 中有一个简单的查询,它以一对多的关系连接两个表。大致定义如下...

class Users( tag: Tag ) extends Table[ User ]( tag, "users" )
    // each field here...
    def * = ( id, name ).shaped <> ( User.tupled, User.unapply)

class Items( tag: Tag ) extends Table[ Item ]( tag, "items" )
    // each field here...

    // foreign key to Users table
    def userId = column[ Int ]( "user_id")
    def user_fk = foreignKey( "users_fk", userId, Users )( _.id )
    def * = ( id, userId.?, description ).shaped <> ( Item.tupled, Item.unapply)

一个用户可以有多个项目。我想要编组的用户案例 class 看起来像...

case class User(id: Option[Int] = None, name:String, items:Option[List[Item]] = None)

然后我用这样的隐式连接查询数据库...

for{
    u <- Users
    i <- Items 
      if i.userId === u.id
  } yield(u, i)

这个"runs"很好。但是,查询显然会为属于用户的每个 "Item" 复制 "Users" 记录...

List(
(User(Some(1),"User1Name"),Item(Some(1),Some(1),"Item Description 1")), 
(User(Some(1),"User1Name"),Item(Some(2),Some(1),"Item Description 2")))

是否有一种优雅的方式将 "many" 部分拉入用户案例 class?无论是 Slick 还是 Scala。我最理想的结局是...

User(Some(1),"User1Name",
    List(Item(Some(1),Some(1),"Item Description 1"),
         Item(Some(2),Some(1),"Item Description 2")))

谢谢!

一种在 Scala 中实现的方法:

val results = List((User(Some(1), "User1Name"), Item(Some(1), Some(1), "Item Description 1")),
                   (User(Some(1), "User1Name"), Item(Some(2), Some(1), "Item Description 2")))

val grouped = results.groupBy(_._1)
                     .map { case (user, item: List[(User, Item)]) =>
                       user.copy(items = Option(item.map(_._2))) }

这处理多个不同的 Users(grouped 是一个 Iterable[User])。