我可以 select Slick 中的一行也保证是唯一返回的行吗?
Can I select a single row in Slick that is also guaranteed to be the only row returned?
在 Slick 中,结果集的第一行有 first
和 firstOption
到 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
,你会在 运行 时得到一个结果或一个错误。
在 Slick 中,结果集的第一行有 first
和 firstOption
到 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
,你会在 运行 时得到一个结果或一个错误。