代码之家  ›  专栏  ›  技术社区  ›  Cory Klein

是否创建一个从可选ID筛选的光滑查询?

  •  0
  • Cory Klein  · 技术社区  · 7 年前

    我想查询一个对象 id ,但是如果 fooId 还提供了,然后我希望将其包含在查询中。

    def getById(id: Long, fooIdOpt: Option[Long]): Future[Option[Bar]] = {
      val query = for {
        b <- bars if b.id === id && fooIdOpt.fold(true)(b.fooId === _)
      } yield {            // Compiler error here ^
        b
      }
      db.run(query.result.headOption)
    }
    

    这里的问题是 fooIdOpt.fold(true)(b.fooId === _) 需要返回 Rep[Boolean] 但是我要用一个 Boolean -明显违反 fold 的方法签名。

    但是我似乎找不到通过 布尔[布尔] 评估结果为 true 作为折叠初始值设定项。在黑暗中射击,我试过了 Rep(true) LiftedLiteral[Boolean](true) 但都不太管用。

    我可以放弃 折叠 完全符合:

    b <- bars if {
      val rep1 = b.id === id
      fooIdOpt.map(fooId => rep1 && b.fooId === fooId).getOrElse(rep1)
    }
    

    但这似乎太复杂了, fooIdOpt match { case Some ... 看起来不会好很多。

    1. 有没有办法实例化一个 布尔[布尔] 始终计算为的文本 ?
    2. 如果没有,除了我的尝试还有别的选择吗? 折叠 , map match 上面允许我构建一个查询,可以选择比较 卵形的 价值?
    2 回复  |  直到 7 年前
        1
  •  2
  •   Leo C    7 年前

    正如您已经了解到的那样, ifEmpty 值类型 fold 需要与…相匹配 b.fooId === _ ,这就是 Rep[Boolean] .一种方法是应用 bind 毫无生气 值如下所示:

    val query = for {
      b <- bars if b.id === id && fooIdOpt.fold(true.bind)(b.fooId === _)
    } yield b
    
        2
  •  1
  •   Cory Klein    7 年前

    另一个选择是 相当地 和其他选择一样糟糕:

    (fooIdOpt.toList.map(b.fooId === _) :+ (b.id === id)).reduceLeft(_ && _)