【问题标题】:Slick 3: How to construct dynamic filter with optional column?Slick 3:如何使用可选列构建动态过滤器?
【发布时间】:2018-02-18 14:04:45
【问题描述】:

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

标准

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

但我收到编译错误:

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

如果我像这样将get 添加到model.description

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

编译正常,但抛出运行时异常:

slick.SlickException:在计算默认值时捕获异常 for Rep[Option[_]].getOrElse -- 当 数据库端需要值

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

【问题讨论】:

    标签: scala filter slick


    【解决方案1】:

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

    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),基本上它将过滤器应用于查询,否则它只返回原始查询。

    【讨论】:

    • 查看问题中的变量名称,您的回答代码看起来令人困惑。您能否提供周围的代码来阐明您的示例中的“标准”和“模型”是什么?
    猜你喜欢
    • 2020-04-19
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 2017-01-25
    相关资源
    最近更新 更多