带有<>的映射投影在Slick中使用伴随对象的案例类

时间:2013-03-02 14:37:33

标签: scala slick

使用Slick,我试图将数据库表条目直接投影到它们所代表的案例类。在example in the documentation之后,我使用<>运算符设置了映射投影:

case class SomeEntity3(id: Int, entity1: Int, entity2: Int)

val SomeEntityTable = new Table[SomeEntity3]("some_entity_table") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def entity1 = column[Int]("entity1")
  def entity2 = column[Int]("entity2")

  def * = id ~ entity1 ~ entity2 <> (SomeEntity3, SomeEntity3.unapply _)
}

现在,我想为SomeEntity3添加一些静态常量和辅助方法。为此,我创建了一个伴侣对象。但只要我加入

object SomeEntity3

对于*的定义,会出现一个非常疯狂的多行错误,说明“使用替代方法重载方法值&lt;&gt;”这些内容难以理解。

伴侣对象如何与Slick中的双向映射相关,我能以某种方式实现我的目标吗?

4 个答案:

答案 0 :(得分:9)

修复非常简单:

def * = id ~ entity1 ~ entity2 <> (SomeEntity3.apply _, SomeEntity3.unapply _)

答案 1 :(得分:8)

案例类的伴随对象通常是从案例类的第一个参数列表到案例类的函数。所以,如果你有

case class Fnord(a: A, b: B, c: C)(d: D)

Scala编译器会自动生成类似于

的伴随对象
object Fnord extends ((A, B, C) => Fnord) {
  ...
}

现在,只要您自己明确说明了伴随对象的某些内容,编译器就不再生成FunctionN扩展内容。因此,大多数情况下自己添加它是个好主意。在您的情况下,这意味着定义SomeEntity3的伴侣,如此:

object SomeEntity3 extends ((Int, Int, Int) => SomeEntity3) {
  ...
}

此行为也存在(长期开放)问题: https://issues.scala-lang.org/browse/SI-3664

答案 2 :(得分:1)

另一种方法是将对象apply方法转换为元组并将其传递给&lt;&gt;如下图所示。

package models

import play.api._
import play.api.libs.json._
import scala.slick.driver.H2Driver.simple._

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

object User {
  implicit val format = Json.format[User]
}

class UserTable(tag: Tag) extends Table[User](tag, "USERS") {
  def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
  def name = column[String]("NAME", O.NotNull)

  def * = (name, id.?) <> ((User.apply _).tupled, User.unapply)
}

object Users extends TableQuery(new UserTable(_)) {
  val findByID = this.findBy(_.id)
}

答案 3 :(得分:0)

就个人而言,案例类中部分应用的apply方法不适用于我的设置和Slick 3.0。

然而,这可以工作,间接挖掘正确的tupled方法:

class WidgetTable(tag: Tag) extends Table[WidgetEntity](tag, "widget_tbl") {

    def id = column[Int]("id",O.PrimaryKey)
    def foo = column[String]("foo")

    override def * = (id,foo) <> ((WidgetEntity.apply _).tupled,WidgetEntity.unapply)
}

查看完整详情:https://stackoverflow.com/a/38589579/564157