firstOption在光滑3.0中显示错误并播放2.4

时间:2015-06-23 21:04:33

标签: scala playframework slick securesocial

我在我的项目中集成了剪影(一个securesocial的分支)作为身份验证库,因此我正在使用光滑的 play-silhouette-slick-seed

来跟踪它的示例项目

在编写these lines时,我在eclipse中遇到了很多错误。

def find(loginInfo: LoginInfo) = {
  DB withSession { implicit session =>
    Future.successful {
      slickLoginInfos.filter(
        x => x.providerID === loginInfo.providerID && x.providerKey === loginInfo.providerKey
      ).firstOption match {
        case Some(info) =>
          slickUserLoginInfos.filter(_.loginInfoId === info.id).firstOption match {
            case Some(userLoginInfo) =>
              slickUsers.filter(_.id === userLoginInfo.userID).firstOption match {
                case Some(user) =>
                  Some(User(UUID.fromString(user.userID), loginInfo, user.firstName, user.lastName, user.fullName, user.email, user.avatarURL))
                case None => None
              }
            case None => None
          }
        case None => None
      }
    }
  }
}

[错误是预期的,因为示例项目是使用旧版本的播放和光滑的编写的]

我试图迁移它们所以我用runO替换了withSession和headOption的firstOption,因为我在光滑的官方文档中读到了以前的版本已经在光滑的3.0中被弃用了。以下是我的更改,但仍无效

def find(loginInfo: LoginInfo) = {
   DB run { 
     Future.successful {
        slickLoginInfos.filter(
          x => x.providerID === loginInfo.providerID && x.providerKey === loginInfo.providerKey
        ).result.headOption match {
          case Some(info) =>
            slickUserLoginInfos.filter(_.loginInfoId === info.id).result.headOption match {
              case Some(userLoginInfo) =>
                slickUsers.filter(_.id === userLoginInfo.userID).result.headOption match {
                  case Some(user) =>
                    Some(User(UUID.fromString(user.userID), loginInfo, user.firstName, user.lastName, user.fullName, user.email, user.avatarURL))
                  case None => None
                }
              case None => None
            }
          case None => None
        }
     }
  }
}

我是新手和scala,每天都在探索新事物。你能帮我解决这些错误吗?如果任何人都能解释我对未来值的使用,它对我们使用 Await(db.run(....))获得的正常值有何益处以及如何解析一个值,那将是值得注意的因为我在一些地方看到他们使用地图和他们在成功或案例中使用的一些地方,所以在未来对象中的价值,它几乎令人困惑。处理未来价值观的最佳方式是什么?

1 个答案:

答案 0 :(得分:0)

查找joinLeft,如果没有匹配,将使用Option作为右侧(joinRight左侧)。所以,你想要的东西是:

val q1 = for {
  (loginInfo, userLoginInfo) <- slickLoginInfos.filter(...) joinLeft slickUserLoginInfos on (_.id === _.loginInfoId)
} yield (loginInfo, userLoginInfo)
val q2 = for {
  ((loginInfo, userLoginInfo), user) <- q1 joinLeft slickUsers.filter(...) on (_._2.loginInfoId === _.id)
} yield {
   // use loginInfo, userLoginInfo and user are optional
}

userLoginInfouser OptionSomeNoneq2取决于是否有任何匹配。您可以在其上运行此headOptiondao.fetch().map(_.toString) 以获得整体结果。

期货

以前,你会做类似的事情:

dao.fetch()

其中Seq[Int]返回Future[Seq[Int]]。现在,使用Slick 3.0,这将是.map,这意味着您只需要另一个flatMap(或dao.fetch().map(_.map(_.toString)) ):

Future

继续像以前一样做,除了它现在包裹在Future中。使用xsd有一些好处,因为您不需要为每次调用数据库阻塞线程。