如何在Slick 3中对不同类型的列上的算术运算过滤记录

时间:2017-03-31 15:27:20

标签: scala slick-3.0

例如,我有这个简化的模型,其中时间戳和持续时间都代表秒。

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]

将持续时间设置为Long

2 个答案:

答案 0 :(得分:1)

根据Slick文档COMING FROM SQL TO SLICK

  

不同类型的算术运算需要使用.asColumnOf[T]进行显式强制转换。

正如您已经发现的那样,您必须明确地将duration投射到Longx.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]),因此报告错误。