光滑的动态可选查询或OR过滤器

时间:2015-01-27 09:01:02

标签: scala slick scalaquery

我有一个问题,我几天都无法解决,

我想根据我的可选值进行动态查询。如果定义了一个值,我想查询所选结果,否则给我*表的投影。 因为在理解中不可能将Lift Embedding DSL和普通的Scala代码混合在一起,还有其他方法可以实现吗?

val x: Option[String] = Some("John")

看似或做事的事情

val result = for {
   w <- workers if (x.isDefined) w.name === x else * projection 
}

此外,是否有可能编写具有可选参数的函数并将其链接到将在WHERE子句OR条件中生成的查询中?对于动态数量的OPTIONAL参数,我设法用MaybeFilter做了这个,但仅用于AND条件。

case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq])     {
  def filteredBy(op: Option[_])(f: (X) => Column[Option[Boolean]]) = {
    op map { o => MaybeFilter(query.filter(f)) } getOrElse { this }
  }
}

implicit def maybeFilterConversor[X, Y](q: Query[X, Y, Seq]) = new MaybeFilter(q)

val x: Option[String] = Some("Ana")
val y: Option[String] = Some("Lemic")

val result = for { r <- radnik.filteredBy(x)(_.ime === x).filteredBy(y)(_.prz === y).query } yield r

prints out select x2.`Mbr`, x2.`Ime`, x2.`Prz`, x2.`Sef`, x2.`Plt`, x2.`Pre`, x2.`God` from `radnik` x2 where (x2.`Ime` = 'Ana') and (x2.`Prz` = 'Lemic')

我需要一个链接任意数量的可选条件的函数,比如filteredBy,但这会产生一个OR过滤器绑定到它,以实现像

这样的东西
select x2.`Mbr`, x2.`Ime`, x2.`Prz`, x2.`Sef`, x2.`Plt`, x2.`Pre`, x2.`God` from `radnik` x2 where (x2.`Ime` = 'Ana') or (x2.`Prz` = Lemic') or (x2.`God` >= '1950')

like filteredBy(someth).orFilteredBy(someth).filteredBy(someth)

提前致谢。

1 个答案:

答案 0 :(得分:0)

正如官方documentation所示,您可以构建动态过滤条件,如下所示:

val x: Option[String] = Some("Ana")
val y: Option[String] = Some("Lemic")

val result = radnik.filter { r =>
  List(
      x.map(radnik.ime === _),
      y.map(radnik.prz === _)
  ).collect({case Some(criteria)  => criteria}).reduceLeftOption(_ || _).getOrElse(true: Rep[Boolean])
}