首页 文章

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

提问于
浏览
3

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

Criteria

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

Table mapping

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)
  }

Filter

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])
}

但我收到编译错误:

value &&不是slick.lifted.Rep [1] [error] .reduceLeftOption(&& _) . getOrElse(true:Rep [Boolean])的成员

如果我像这样添加 getmodel.description

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

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

slick.SlickException:在计算Rep [Option [_]]的默认值时捕获异常.getOrElse - 当数据库端需要该值时,这不能懒得做

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

1 回答

  • 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 ),它会将过滤器应用于查询,否则它只返回原始查询 .

相关问题