例如,我有这个简化的模型,其中时间戳和持续时间都代表秒。
case class Item(id: Int, : Long, duration: Int)
val max_timestmap: Long = ???
val stmt = items.filter(x => (x.timestamp + x.duration) <= max_timestamp)
db.run(stmt.result)
上面的编译不会跟随我很难理解的错误。
ambiguous implicit values:
[error] both value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Option[Boolean]]]
[error] and value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[Boolean]
[error] match expected type slick.lifted.CanBeQueryCondition[Nothing]
[error] filter(x => (x.timestamp + x.duration) <= max_timestamp)
更新1 :
似乎问题源于timestamp
为长而duration
为Int的事实。当两者具有相同的数据类型时,它似乎是编译的。
更新2 :
我找到了这个解决方案。使用x.duration.asInstanceOf[Rep[Long]]
或可能更合适的x.duration.asColumnOf[Long]
答案 0 :(得分:1)
根据Slick文档COMING FROM SQL TO SLICK:
不同类型的算术运算需要使用
.asColumnOf[T]
进行显式强制转换。
正如您已经发现的那样,您必须明确地将duration
投射到Long
:x.duration.asColumnOf[Long]
。
答案 1 :(得分:1)
虽然在告诉确切问题时没有多大帮助,但如果在Query.scala中查看方法filter
和特征/对象CanBeQueryCondition
,则错误消息有意义:
sealed abstract class Query[+E, U, C[_]] extends QueryBase[C[U]] { self =>
...
def filter[T <: Rep[_]](f: E => T)(implicit wt: CanBeQueryCondition[T]): Query[E, U, C] =
withFilter(f)
...
}
...
trait CanBeQueryCondition[-T] extends (T => Rep[_])
object CanBeQueryCondition {
implicit val BooleanColumnCanBeQueryCondition : CanBeQueryCondition[Rep[Boolean]] =
new CanBeQueryCondition[Rep[Boolean]] {
def apply(value: Rep[Boolean]) = value
}
implicit val BooleanOptionColumnCanBeQueryCondition : CanBeQueryCondition[Rep[Option[Boolean]]] =
new CanBeQueryCondition[Rep[Option[Boolean]]] {
def apply(value: Rep[Option[Boolean]]) = value
}
implicit val BooleanCanBeQueryCondition : CanBeQueryCondition[Boolean] =
new CanBeQueryCondition[Boolean] {
def apply(value: Boolean) = new LiteralColumn(value)
}
}
正如@Federico Pellegatta所指出的,对于隐式参数T
,显式强制转换要求导致Nothing
= T <: Rep[_]
(CanBeQueryCondition[T]
),因此报告错误。