我可以 select Slick 中的一行也保证是唯一返回的行吗?

Can I select a single row in Slick that is also guaranteed to be the only row returned?

在 Slick 中,结果集的第一行有 firstfirstOption 到 select。

是否有一个版本也保证这是唯一返回的行(这样,如果数据集以某种方式破坏了我的应用程序所依赖的某些假设,我会得到一个异常)?

我不知道有什么内置的东西可以做到这一点。您可以做的是编写一个方法来执行操作,检查结果恰好是一行,如果不是则失败。

这可能只是一个简单的旧方法,您可以围绕一个动作。或者,我们可以丰富一个动作,使其成为您对动作的调用。这是我的意思的例子:

implicit class ResultEnrichment[T](action: DBIO[Seq[T]]) {
  def exactlyOne: DBIO[T] = action.flatMap { xs =>
    xs.length match {
      case 1 => DBIO.successful(xs.head)
      case n => DBIO.failed(new RuntimeException(s"Expected 1 result, not $n"))
    }
  }
}

这个 class 被标记为隐式的,因此只要有 DBIO[Seq[T]],编译器就可以使用它。具体来说,它提供了一个 exactlyOne 方法,编译器可以在 Seq[T].

的任何操作中找到该方法

exactlyOne 的结果是您可以 运行 的新操作。如果在 运行 时间没有找到恰好一行,它将失败。

您可以像这样使用它来进行任意查询:

val query = table.filter(...).map(...) // whatever your query is
val action = query.result.exactlyOne

运行 最后一个 action,你会在 运行 时得到一个结果或一个错误。