简体   繁体   中英

Slick filter when comparing value and column is Option

have a table where formDefinitionId is nullable column in Postgres DB (9.3) . Slick version is 2.1.0

we have a this filter on a query

table.filter(_.formDefinitionId === request.formDefinitionId)

request.formDefinitionId where request is nothing but a Scala case class with formDefinitionId as an Option[Int]

case class Request(formDefinitionId : Option[Int])

now when request.formDefinitionId is None slick generates following query

(x2."form_definition_id" = null)

vs

(x2."form_definition_id” IS NULL) - this is what Postgres expects

Work around is to create a different filter based on request.formDefinitionId

eg

request.formDefinitionId match {
  case Some(fid) => table.filter(_.formDefinitionId === fid)
  case None => table.filter(_.formDefinitionId.isNull)
}

however creating such condition for every property which is Option isn't feasible - there exists numerous Option properties across many tables. Is there a better/generic way to achieve this? I would imagine this is a common scenario with people using Slick

Didn't test (I don't have a Slick setup here).

But as = null returns nothing, shouldn't something like this work?

 table.filter(r => r.formDefinitionId.isNull || r.formDefinitionId === fid)

You can use the following solution with Slick 3.3.x:

table
  // case 1: both are empty
  .filterIf(request.formDefinitionId.isEmpty)(_.formDefinitionId.isEmpty)
  // case 2: both are defined and equal
  .filterOpt(request.formDefinitionId)(_.formDefinitionId === _)

case 1 corresponds the following SQL:

 select * from table1 when form_definition_id is null;

case 2:

 select * from table1 when form_definition_id = ?;

I am a newer to slick and now also confused with this problem. Maybe it's toolate to you.I wanted to do some search with different column(Option[text]). Here is my code ,It is worked to me.

val someone1 = cou.filter(_.id === id_S)

val someone2 = cou.filter(_.first_name === first)

val someone3 = cou.filter(_.last_name === last)

val someone = (someone1) union (someone2) union (someone3)

dbConfig.db.run(someone.result).map(_.toList)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM