使用 Slick 输入投影

Posted

技术标签:

【中文标题】使用 Slick 输入投影【英文标题】:Typed projection with Slick 【发布时间】:2017-07-29 17:48:25 【问题描述】:

我正在尝试在查询端定义一个类型来映射我的连接,这样我就可以避免返回一个我必须手动应用于我的投影案例类发布查询的值的元组。

给定这样的关系:

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]

我想在查询端创建一个类型,其形状类似于:

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

这样我就可以得到如下函数签名:

Query[ChildParentProjection, ChildWithParentName, Seq]

在 slick 中可能吗?

【问题讨论】:

【参考方案1】:

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

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

希望我能理解你的问题

【讨论】:

谢谢。我不知道&lt;&gt; 可以应用于查询级别。由此产生的MappedProjection 正是我想要完成的,而且比我想象的要简单得多,即不需要ChildParentProjection。还有一个问题:在q 之前可以很容易地在sortBy 中使用,但我似乎无法提取元组或ChildWithParentName from MappedProjection`

以上是关于使用 Slick 输入投影的主要内容,如果未能解决你的问题,请参考以下文章

怎么利用matlab做一张地图的投影

当伴生对象在类中时使用 .tupled 方法

使用全景创建 360° x 180° 球面投影

MapGIS投影变换出错

OpenCV——反向投影(定位模板图像在输入图像中的位置)

opencvprojectPoints 三维点到二维点 重投影误差计算