光滑3:如何使用可选列构建动态过滤器?

时间:2018-02-18 14:04:46

标签: scala filter slick

我需要根据涉及的一些标准构建动态过滤器 可选栏:

标准

case class Criteria(
  name: Option[String] = None,
  description: Option[String] = None,
)

表格映射

class OrganizationsTable(tag: Tag) extends Table[OrganizationModel](tag, "organizations") {
    def id = column[Long]("id", O.PrimaryKey)
    def name = column[String]("name")
    def description: Rep[Option[String]] = column[Option[String]]("description")

    def * = (id, name, description) <> ((OrganizationModel.apply _).tupled, OrganizationModel.unapply)
  }

过滤

organizations.filter { model =>      

  List(
    criteria.name.map(model.name.like(_)),
    criteria.description.map(v => model.description.isDefined && model.description.like(v))
  )
  .collect({case Some(cr)  => cr})
   // value && is not a member of slick.lifted.Rep[_1]
  .reduceLeftOption(_ && _).getOrElse(true: Rep[Boolean])
}

但是我收到了编译错误:

  

价值&amp;&amp;不是slick.lifted.Rep [ 1] [错误]的成员   .reduceLeftOption(&amp;&amp; _)。getOrElse(true:Rep [Boolean])

如果我将get添加到model.description,请执行以下操作:

criteria.description.map(v => model.description.isDefined && model.description.get.like(v))

它编译得很好,但会抛出运行时异常:

  

slick.SlickException:计算默认值时捕获异常   对于Rep [Option [_]]。getOrElse - 这不能在懒惰时完成   数据库端需要值

如何在涉及可选列的光滑构建动态查询?

1 个答案:

答案 0 :(得分:2)

这是我在工作项目中使用的实用程序:

implicit class OptionFilter[E, U, C[_]](query: Query[E, U, C]) {
  import slick.lifted.CanBeQueryCondition
  def optionalFilter[O, T <: Rep[_]](op: Option[O])(f:(E, O) => T)(
    implicit wt: CanBeQueryCondition[T]): Query[E, U, C] =
      op.map(o => query.withFilter(f(_,o))).getOrElse(query)
}

用法

criteria.optionalFilter(model.description)(_.description.? like _)

基本上,如果定义了目标值(例如model.description),它会将过滤器应用于查询,否则它只返回原始查询。