scala 将光滑的结果保存到新对象中

scala save slick result into new object

有没有办法将灵活查询的结果保存到新对象中?

这是我的圆滑结果,列表中只有一个"object"

val result: Future[Seq[ProcessTemplatesModel]] = db.run(action)

结果应该映射到 ProcessTemplatesModel,因为我想访问这样的值

process.title

这可能吗?

谢谢

TL;DR: 你应该尽可能长时间地保留上下文。

Future 表示该值将在未来某个时间给出(这就是我所说的值的某些上下文)。

使用它的糟糕方法是阻塞您的线程,直到找到该值,然后再使用它。

更好的方法是告诉你的程序:"Once the value is found (whenever that is), do something with it"。这是一个延续,或回调,并在 scala 中用 mapflatMap 实现。

Seq 是您的价值的另一个背景。这意味着您实际上有不同的可能值。如果你想确保你最多有一个值,你总是可以做 seq.headOption 将上下文从 Seq 切换到 Option.

使用它的糟糕方法是直接取第一个值而不去检查它是否存在。

更好的方法是告诉你的程序:"No matter how many values you have, do this for each of them"。

现在,你如何在上下文中工作?您使用 Functor and/or Monad 运算符:mapflatMap.

例如,如果您想将函数 convertToSomethingElse 应用于上下文的每个元素,只需执行

result.map(list => list.map(process => convertToSomethingElse(process))

你会得到一个 Future[Seq[SomethingElse]]

再比如,如果你想把结果保存到别处,你可能会有一些IO,或者数据库操作,这可能需要一些时间,而且可能会失败。我们假设您有一个函数 save(entity: ProcessTemplateModel): Future[Boolean] 可以让您保存您的模型之一。该函数将花费一些时间(并且它将在另一个线程中启动)并且可能失败的事实在 return 类型 Future[Boolean] 中可见(Boolean 在这里并不重要,它是事实上,我们再次拥有重要的 Future 上下文)。

在这里,您必须执行(假设您只想保存列表中的第一个元素):

val savedFirstResult: Future[Option[ProcessTemplatesModel]] = result.flatMap {list => 
  Future.traverse(list.headOption){ process =>  //traverse will switch the Future and Option contexts
    save(process)
  }
}

因此,如您所见,我们可以通过留在 Slick returned 的上下文中来完成我们想做的大部分事情。你不应该想离开他们,因为

  • 大多数情况下,当您 map 在上下文中使用一些函数来获取上下文外的值时,大多数时候没有必要这样做
  • 提取方法大多数时候是不安全的:Option#get如果没有元素在Option中会抛出异常,Await.result(future, duration)可能会阻止所有计算或抛出异常
  • Play 中的响应!可以在控制器中作为 Futures 给出,使用 Action.async