使用 Slick 的类型化投影
Typed projection with Slick
我正在尝试在查询端定义一个类型来映射我的连接,这样我就可以避免返回我必须手动应用于我的投影案例的值元组 class post查询。
给定如下关系:
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]
我想投射到案例 class 中,例如:
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)
我把它放在一个函数中并允许 children
和 parents
被参数化。该函数不会 运行 查询,因为有时我想要 .result
有时我想要 .result.headOption
,所以我的函数签名是:
Query[(Rep[Int], Rep[String], Rep[String]), (Int, String, String), Seq]
我想在查询端创建一个类似于以下形状的类型:
class ChildParentProjection(val id: Rep[Int],
val name: Rep[String],
val parentName[String])
这样我就可以获得像这样的函数签名:
Query[ChildParentProjection, ChildWithParentName, Seq]
slick 可以吗?
我真的不明白你为什么要使用 class ChildParentProjection
。
如果你想 return a Seq[ChildWithParentName]
在查询上执行 result
时,你必须将你的 monadic join 产生的元组映射到 ChildWithParentName
class 像这样:
val q = for {
c <- children
p <- parents if c.parentId === p.id
} yield (c.id,c.name,p.name) <> (ChildWithParentName.tupled,ChildWithParentName.unapply)
我希望我已经理解你的问题
我正在尝试在查询端定义一个类型来映射我的连接,这样我就可以避免返回我必须手动应用于我的投影案例的值元组 class post查询。
给定如下关系:
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]
我想投射到案例 class 中,例如:
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)
我把它放在一个函数中并允许 children
和 parents
被参数化。该函数不会 运行 查询,因为有时我想要 .result
有时我想要 .result.headOption
,所以我的函数签名是:
Query[(Rep[Int], Rep[String], Rep[String]), (Int, String, String), Seq]
我想在查询端创建一个类似于以下形状的类型:
class ChildParentProjection(val id: Rep[Int],
val name: Rep[String],
val parentName[String])
这样我就可以获得像这样的函数签名:
Query[ChildParentProjection, ChildWithParentName, Seq]
slick 可以吗?
我真的不明白你为什么要使用 class ChildParentProjection
。
如果你想 return a Seq[ChildWithParentName]
在查询上执行 result
时,你必须将你的 monadic join 产生的元组映射到 ChildWithParentName
class 像这样:
val q = for {
c <- children
p <- parents if c.parentId === p.id
} yield (c.id,c.name,p.name) <> (ChildWithParentName.tupled,ChildWithParentName.unapply)
我希望我已经理解你的问题