【问题标题】:Future and Option in for comprehension in slickFuture 和 Option in for slick 中的理解
【发布时间】:2018-10-13 23:17:36
【问题描述】:

我在使用 slick 方面非常新,现在我面临如何从两个表中检索一些数据的问题。 我有一张桌子

class ExecutionTable(tag: Tag) extends Table[ExecTuple](tag, "execution") {
  val id: Rep[String] = column[String]("id")
  val executionDefinitionId: Rep[Long] = column[Long]("executionDefinitionId")
  // other fields are omitted

  def * = ???
}

还有一张桌子

class ServiceStatusTable(tag: Tag)
  extends Table[(String, Option[String])](tag, "serviceStatus") {
  def serviceId: Rep[String] = column[String]("serviceId")
  def detail: Rep[String] = column[String]("detail")

  def * = (serviceId, detail.?)
}

在 Dao 中,我将这两个表中的数据转换为业务对象

case class ServiceStatus(
  id: String, 
  detail: Option[String] = None, //other fields
)

喜欢这个

private lazy val getServiceStatusCompiled = Compiled {
  (id: Rep[String], tenantId: Rep[String]) =>
  for {
    exec   <- getExecutionById(id, tenantId)
    status <- serviceStatuses if exec.id === status.serviceId
  } yield mapToServiceStatus(exec, status)
}

以后

def getServiceStatus(id: String, tenantId: String)
: Future[Option[ServiceStatus]] = db
  .run(getServiceStatusCompiled(id, tenantId).result.transactionally)
  .map(_.headOption)

问题在于表execution 中的所有条目并非都存在表serviceStatus 中的条目。我无法修改表 execution 并将其添加到字段 details,因为它只是特定于服务的。 当我运行查询时,如果来自execution 的条目存在serviceStatus 中的条目,所有工作都按预期工作。但如果serviceStatus 中没有条目,则返回Future[None]。 问题:根据表serviceStatus 中的现有条目或其他解决方法,是否有任何选项可以将status 理解为选项?

【问题讨论】:

  • Future[None] 如果没有serviceStatus 记录该id 看起来是一个不错的答案,那么您想要得到什么答案?看起来您要求获得没有状态的id 的状态,这显然是不可能的。如果你想要一个默认状态,那么你可以在Option 上使用getOrElse,但这似乎不是你想要的。
  • 在服务状态表中,你没有映射到case class def * = (serviceId, detail.?) (ServiceStatus.tupled, ServiceStatus.unapply) 同样的情况是*ExecutionTable 里面你没有这个方法的实现。
  • 感谢所有回复的人。是的,代码没有编译,但我想传达问题的症结所在。是的,Option[ServiceStatus] 是很好的变体,但我不知道如何获得它

标签: scala slick


【解决方案1】:

通常,如果连接条件在“右”表中没有找到对应的记录,但结果仍应包含“左”表中的行,则使用左连接。 在您的情况下,您可以执行以下操作:

Execution
  .filter(...execution table filter...)
  .joinLeft(ServiceStatus).on(_.id===_.serviceId)

这会给你一对

(Execution, Rep[Option[ServiceStatus]]) 

查询执行后:

(Execution, Option[ServiceStatus])      

【讨论】:

  • 这正是我想要的。非常感谢!
猜你喜欢
  • 2014-11-19
  • 2013-02-15
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 2019-05-25
  • 2015-10-09
  • 2016-11-08
相关资源
最近更新 更多