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
How to parametrize Scala Slick queries by WHERE clause conditions?
答案 0 :(得分:7)
Slick没有关于C
的任何信息,因此它不知道它是否可以以及如何将其映射到数据库值以及它是否可以使用===
。所以你得到一个类型错误。您将不得不使用Scala的类型系统将类型限制为Slick知道如何映射它的类型。您可以通过提供所谓的上下文绑定来实现此目的,在本例中为:BaseColumnType
。
def whereEq[C:BaseColumnType](col: RichTable.this.type => Column[C], c: C) = {
q.filter { fields =>
col(fields) === c
}
}
Slick提供了 BaseColumnType
,并以这种方式使用它基本上告诉Scala编译器在范围内查找类型为BaseColumnType[C]
的隐式值,其中调用 { {1}}。因为通常知道whereEq
实际上是什么。 Slick带有C
,BaseColumnType[Int]
等,所以在调用网站上,当BaseColumnType[String]
真的是C
或Int
时,Scala编译器可以找到一个在那个特定的电话中,这种方式将信息进一步传递给Slick。
LiuTiger的问题也是如此。 String
应该做的伎俩,特征不适用于上下文边界。实现抽象DAO时,要准备好面对很多挑战,并掌握Scala类型系统技能的优势,并学习类型推断顺序,隐式参数等等。