我需要根据涉及的一些标准构建动态过滤器 可选栏:
标准
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 - 这不能在懒惰时完成 数据库端需要值
如何在涉及可选列的光滑构建动态查询?
答案 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
),它会将过滤器应用于查询,否则它只返回原始查询。