我正在尝试进行几次相关的Slick / DB调用,然后在旋转模板中显示结果数据。
def show(slug: String) = Action.async { implicit rs =>
for {
f <- fooDAO.findBySlug(slug) // f is of type Option[foo]
fid <- f.flatMap(a => a.id.map(b => b)) // fid is of type Long
b <- barDAO.findByFooId(fid) // b is of type Seq[bar]
} yield {
f.map {
case Some(f) => Ok(views.html.foobar(f, b))
case _ => NotFound
}
}
}
我首先需要获得&#34; ID&#34;然后能够查询其他相关数据。编译器现在产生此错误:
play.sbt.PlayExceptions$CompilationException: Compilation error[type mismatch;
found : scala.concurrent.Future[Option[play.api.mvc.Result]]
required: Option[?]]
非常感谢任何帮助。
答案 0 :(得分:1)
您的代码存在一个根本性缺陷,因为您在同一理解中混合Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
和Option
预计for-comprehension将在同一个&#34;容器&#34; type,它将是Seq
e.g。如果您合并多个yield
,则会获得Option
,如果合并Option
,则会获得Seq
。
在这种情况下,您可以通过将Seq
(foo)转换为Option
来解决此问题(如果foo为Seq
则为空,如果不是,则为1)
最终结果将是
None
但我猜这不是你需要的。我想您希望获取与检索到的val results: Seq[(Foo, Bar)] =
for {
f <- fooDAO.findBySlug(slug).toSeq // f is of type Seq[Foo]
b <- barDAO.findByFooId(f.id) // b is of type Seq[Bar]
} yield (f, b)
相关联的所有Bar
(如果有),并将其与您的模板一起展示。如果Foo
没有Foo
,则需要slug
。
我们可以这样做
NotFound
您可以通过定义支持方法
来使其更明确def show(slug: String) = Action.async { implicit rs =>
val f = fooDAO.findBySlug(slug) // f is of type Option[Foo]
f.fold(
NotFound,
foo => Ok(views.html.foobar(foo, barDAO.findByFooId(foo.id))
)
}
答案 1 :(得分:0)
理解你在这里想要达到的目标有点棘手,但是如果整个事情都是基于findbySlug
返回Future[Option[Foo]]
,最终结果为NotFound
Option
是None
,那么您的yield
应该只是:{/ p>
...
} yield {
f.fold(NotFound)(foo => Ok(views.html.foobar(foo, b)))
}
Option[T]
是数据检索和控制流的理想类型,但是pattern-matching on it is almost never the right approach。 fold
的使用对于任务非常简洁。