关于 scala:slick 可重用的 InsertAndUpdate 特征 | 珊瑚贝

slick reusable InsertAndUpdate trait


鉴于 DRY,我试图避免在 Slick 表定义中重复插入和更新逻辑。我试过这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
trait Entity {
    def id: Option[Int]
}

case class BankRekening(id: Option[Int], nummer: String, omschrijving: String) extends Entity{
}

object BankRekeningen extends Table[BankRekening](“bankrekening”) with InsertAndUpdate[BankRekening] {
    def id = column[Int](“id”, O.PrimaryKey, O.AutoInc)
    def nummer = column[String](“nummer”)
    def omschrijving = column[String](“omschrijving”)
    def * = id.? ~ nummer ~ omschrijving <> (BankRekening, BankRekening.unapply _)
    def idx_nummer = index(“idx_nummer”, nummer, unique = true)
}

trait InsertAndUpdate[T <: Entity] {
    this: Table[T] =>

    def id: scala.slick.lifted.Column[Int]

    def insert(obj: T): T = {
        obj.copy(id = Some(this.returning(this.id) insert obj))
    }
}

现在编译器在最后一条语句中抱怨 \\’obj\\’,说:找不到 scala.slick.lifted.TypeMapper[T]

类型的证据参数的隐式值

有什么想法吗?

  • 只是一种预感,但是您是否导入了 scala.slick.driver.<yourdbdriver>.simple._?
  • 华夫饼悖论,是的,他有这是”问题”的中间原因(最终是Scalac产生误导性错误消息)。


简单的答案:您尝试在没有复制方法的 T 上调用复制。

长答案:不幸的是,Scalac,Scala 编译器让我们 Slick(无意中)劫持错误消息。您应该看到错误 value copy is not a member of T。在 copy 的情况下,由于 Slick 在范围内的隐含,Scalac 会以某种方式吞下该消息。这是一个简化的复制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
object simple{
    implicit def intColumnType: TypedType[Int] = null
    implicit def valueToConstColumn[T : TypedType](v: T) = ConstColumn(v)
}
import simple._
trait TypedType[T]
case class ConstColumn[T](v: T){
  def bar = 5
}

trait InsertAndUpdate[T] {
    def insert(obj: T): T = {
      5.copy() // <- unexpected, but is valid and compiles fine
      5.bar    // compiles fine

      obj.bar    // error: value bar is not a member of type parameter T
                 // error: could not find implicit value for evidence parameter of type TypedType[T]

      obj.copy() // error: could not find implicit value for evidence parameter of type TypedType[T]
    }
}

如您所见,消息以某种方式被 copy 吞噬了。我也没有发现消息 could not find implicit value for evidence parameter of type TypedType[T] 有帮助。我创建了一个 Scala 票来解决这个问题:https://issues.scala-lang.org/browse/SI-7907

  • 我现在看到 Entity 不是一个案例类,而是一个特征。有一个案例类,因此期望有复制方法。 5.copy 编译是因为 5 ‘是一个案例类’…?
  • 您不能从案例类继承,因此 Entity 不能是案例类。 5 不是案例类。 5.copy() 之所以有效,是因为 ConstColumn 是一个案例类,并且编译器应用 valueToConstColumn 将 5 转换为具有复制方法的东西。 valueToConstColumn 适用于 Int 因为在范围内有一个隐式 TypedType[Int]。但是在复制方法的情况下,这种转换可能不是用户想要的。也许我们应该将 ConstColumn 更改为 Slick 中的普通类以避免这种情况。


来源:https://www.codenong.com/19333322/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?