使用Slick键入投影

时间:2017-07-29 17:48:26

标签: scala slick

我试图在查询端定义一个Type来映射我的连接,这样我就可以避免返回我必须手动应用到我的投影案例类帖子查询的值元组。

给出如下关系:

case class Parent(id: Int, name: String, extra: String)

class ParentTable(tag: Tag) extends Table[Parent](tag, "parent") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def extra = column[String]("extra")
  def * = (id, name, extra) <> (Parent.tupled, Parent.unapply)
}

val parents = TableQuery[ParentTable]

case class Child(id: Int, parentId: Int, name: String, extra:  String)

class ChildTable(tag: Tag) extends Table[Child](tag, "child") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def parentId = column[Int]("parent_id")
  def parent = foreignKey("parent_fk", parentId, parents)(_.id)
  def name = column[String]("name")
  def extra = column[String]("extra")
  def * = (id, parentId, name, extra) <> (Child.tupled, Child.unapply)
}
val children = TableQuery[ChildTable]

我想投射到一个案例类,如:

  case class ChildWithParentName(id: Int, name: String, parentName: String)

联接和投影看起来像:

val q = for {
  c <- children
  p <- parents if c.parentId === p.id
} yield (c.id,c.name,p.name)

我把它放在一个函数中,并允许参数化childrenparents。该函数不运行查询,因为有时我想要.result,有时我想要.result.headOption,所以我的函数签名是:

Query[(Rep[Int], Rep[String], Rep[String]), (Int, String, String), Seq]

我想在Query端创建一个Type,其形状类似于:

class ChildParentProjection(val id: Rep[Int], 
                            val name: Rep[String], 
                            val parentName[String])

这样我就可以获得一个函数签名,如:

Query[ChildParentProjection, ChildWithParentName, Seq]

光滑可能吗?

1 个答案:

答案 0 :(得分:1)

我真的不明白你为什么要使用课程ChildParentProjection。 如果你想在查询上执行Seq[ChildWithParentName]时返回result,那么你必须将你的monadic join产生的元组映射到ChildWithParentName类,如下所示:

val q = for {
c <- children
p <- parents if c.parentId === p.id
} yield (c.id,c.name,p.name) <> (ChildWithParentName.tupled,ChildWithParentName.unapply)

我希望我理解你的问题