如何在Slick中的Option [Boolean]列上进行过滤

Ror*_*ory 5 scala slick slick-3.0

我的数据库中有以下列,多数民众赞成是布尔值,但也接受NULL,因此true,false和NULL都是有效的:

def rtb = column[Option[Boolean]]("rtb")
Run Code Online (Sandbox Code Playgroud)

并从我要过滤的客户端中获取以下可选输入:

rtbFromClient: Option[Boolean] = ... 
Run Code Online (Sandbox Code Playgroud)

我有以下内容(基于有关如何在光滑的查询中进行查询的答案:https : //stackoverflow.com/a/40888918/5300930):

val query = userTable.
      filter(row => 
          if (rtbFromClient.isDefined) 
              row.rtb.get === rtbFromClient.get 
          else 
              LiteralColumn(true)
      )
Run Code Online (Sandbox Code Playgroud)

但是在代码运行时出现此错误:

Caught exception while computing default value for Rep[Option[_]].getOrElse -- This cannot be done lazily when the value is needed on the database side
Run Code Online (Sandbox Code Playgroud)

我认为可能是因为row.rtb.get在调用时抛出异常,因为db中的值为null,所以尝试将其更改为row.rtb.getOrElse(null)和row.rtb.getOrElse(None),但是这些都不起作用)

还尝试了以下方法:

if (rtbFromClient.isDefined) {
    val query = query.filter(_.rtb.isDefined).filter(_.rtb.get === rtbFromClient.get)
}
Run Code Online (Sandbox Code Playgroud)

但这也会在运行时引发相同的错误:

Caught exception while computing default value for Rep[Option[_]].getOrElse -- This cannot be done lazily when the value is needed on the database side
Run Code Online (Sandbox Code Playgroud)

总结一下:

  • 我的数据库中有一个Option [Boolean]列,可以包含true,false或NULL(实际的mysql类型是tinyint(1),它映射到一个光滑的Option [Boolean])
  • 我有一个由用户rtbFromClient提供的可选过滤器,如果存在的话,我想对其进行过滤。如果存在,则为true或false
  • 我还有其他具有类似行为的可选过滤器(此处未显示),因此我希望能够轻松组合它们

Ale*_*kin 5

我遇到过同样的问题。我的解决方案是(使用 Slick 3.3.x 测试):

val query = usersTable.filterOpt(rtbFromClient)(_.rtb === _)
Run Code Online (Sandbox Code Playgroud)

情况1(当rtbFromClient为空时)对应的SQL如下:

select * from users;
Run Code Online (Sandbox Code Playgroud)

情况2(定义了rtbFromClient):

select * from users where rtb = ?;
Run Code Online (Sandbox Code Playgroud)


Ror*_*ory 0

var query = userTable.drop(page.skip).take(page.top)

if (rtbFromClient.isDefined) {
    query = query.filter(row => row.rtb.isDefined && row.rtb === rtbFromClient)
}

// More if blocks with optional filters here
...

dbProvider.db.run(query.result)
Run Code Online (Sandbox Code Playgroud)