6
import scala.slick.driver.MySQLDriver.simple._

class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) {

  case class QueryExt[B](q: Query[RichTable.this.type, B])  {
    def whereEq[C](col: RichTable.this.type => Column[C], c: C) = {
      q.filter { fields =>
        col(fields) === c
      }
    }
  }

}

然后它抱怨

[error] /home/jilen/workspace/play-slick/src/main/scala/play/slick/SlickQueryExtension.scala:10: value === is not a member of slick.driver.MySQLDriver.simple.Column[C]
[error]         col(fields) === c
[error]                     ^
[error] /home/jilen/workspace/play-slick/src/main/scala/play/slick/SlickQueryExtension.scala:9: ambiguous implicit values:
[error]  both value BooleanColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Boolean]]
[error]  and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Option[Boolean]]]
[error]  match expected type scala.slick.lifted.CanBeQueryCondition[Nothing]
[error]       q.filter { fields =>
[error]                ^
[error] two errors found
[error] (compile:compile) Compilation failed
[error] Total time: 0 s, completed Mar 6, 2014 1:21:48 AM

对此有疑问,但答案不适用于 2.0

如何通过 WHERE 子句条件参数化 Scala Slick 查询?

4

1 回答 1

7

Slick 没有关于 的任何信息C,因此它不知道它是否可以以及如何将其映射到数据库值以及是否可以===在其上使用。所以你得到一个类型错误。您将不得不使用 Scala 的类型系统将类型限制为 Slick 知道如何映射它的类型。在这种情况下,您可以通过提供所谓的 Context Bound 来做到这一点:BaseColumnType

def whereEq[C:BaseColumnType](col: RichTable.this.type => Column[C], c: C) = {
  q.filter { fields =>
    col(fields) === c
  }
}

BaseColumnType由 Slick 提供并以这种方式使用它基本上告诉 Scala 编译器BaseColumnType[C]在您调用 whereEq的范围内查找类型的隐式值。因为那时通常会知道C实际情况。Slick 带有BaseColumnType[Int],BaseColumnType[String]等,因此在调用站点上,Scala 编译器可以在您C确实是IntString在该特定调用中找到一个,并通过这种方式将信息进一步传递给 Slick。

刘虎的问题也一样。abstract class Crud[..., PK:BaseColumnType]应该可以解决问题,特征不适用于上下文边界。在实现抽象 DAO 时,要准备好面对许多挑战,并充分利用 Scala 类型系统技能,并学习很多关于类型推断顺序、隐式参数等的知识。

于 2014-03-26T04:31:40.367 回答