Scala 在Slick 3.0中,如何简化嵌套的“db.run”?

Scala 在Slick 3.0中,如何简化嵌套的“db.run”?,scala,slick,slick-3.0,Scala,Slick,Slick 3.0,我正在使用Slick 3.0,以下是我的代码: def registerMember(newMember: TeamMember): Future[Long] = { db.run( teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption ).flatMap { case None => Future(-1) case _ => db.run( (t

我正在使用Slick 3.0,以下是我的代码:

def registerMember(newMember: TeamMember): Future[Long] = {

  db.run(
    teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption
  ).flatMap {
    case None => Future(-1)
    case _ => db.run(
      (teamProfileTable returning teamProfileTable.map(_.staffID)) += newMember.toTeamRecord
    )
  }
}
这看起来不错。但是当有更多的回调层时,代码可能变得难以读取。我尝试使用
for expression
来简化代码,然后
。。但是由于模式匹配部分的原因,我只能使用
flatMap
来实现这一点


有人对如何重构这个有想法吗

我认为在这里理解的方法应该可以,您只需要在第一个
将来的结果中有条件地处理
选项
。类似的东西应该可以工作(注意我没有编译并检查这个):


在Slick 3.0中,当查询跨越两个表时,简化嵌套db.runs的另一种方法是将查询连接到单个查询中。但是,OP在同一个表上嵌套查询的情况似乎比较少见,因此这种方法在特定情况下可能没有帮助

val query = slickLoginInfos join slickUserLoginInfos on 
   ((l,ul) => l.id === ul.loginInfoId) 
db.run((for { (l, ul) <- query } yield (ul)).result.headOption)
val query=slickLoginInfos加入slickUserLoginInfos开启
((l,ul)=>l.id==ul.loginInfoId)

db.run((对于{(l,ul)))您应该组合查询,然后在最后一步在db上运行合成。我认为这就是它应该如何工作的。如果您添加一些代码来制作一个可运行的示例,我可以尝试回答。@pagoda_5b谢谢!但是如果第二个查询取决于第一个查询的结果,如何组合这两个查询呢?我认为
不适用于这里。@hanfeison您可能应该使用它来理解,但如果您不能提供一些自我一致的代码进行测试,我无法进一步帮助您。除非您更明确,否则我可能只能猜测代码的意图和结果。:)
def registerMember(newMember: TeamMember): Future[Long] = {
  def findMember = 
    db.run(teamProfileTable.filter(u => u.ID === newMember.ID).result.headOption

  def addMember(r1Opt:Option[TeamMember]) = {
    r1Opt.fold(Future.successful(-1L)){r1 =>
      db.run((teamProfileTable returning teamProfileTable.map(_.staffID)) += 
        newMember.toTeamRecord)
    }
  }

  for{
    r1Opt <- findMember
    r2 <- addMember(r1Opt)
  } yield r2

}
val query = slickLoginInfos join slickUserLoginInfos on 
   ((l,ul) => l.id === ul.loginInfoId) 
db.run((for { (l, ul) <- query } yield (ul)).result.headOption)