【问题标题】:How do you flatten a Sequence of Sequence in DBIOaction SLICK?如何在 DBIOaction SLICK 中展平序列序列?
【发布时间】:2018-07-13 10:10:31
【问题描述】:

大家好,我是 slick 的新手,我怎样才能使这个序列变平?这样就可以返回注释代码

    def insertIfNotExists(mapCountryStates: Map[String, Iterable[StateUtil]]): Future[Seq[Seq[StateTable]]] /*: Future[Seq[StateTable]]*/ = {
    val interaction = DBIO.sequence(mapCountryStates.toSeq.map { case (alpha2Country, statesUtil) =>
      val codes = statesUtil.map(_.alpha3Code)
      for {
        countryId <- Countries.filter(_.alpha2Code === alpha2Country).map(_.id).result.head
        existing <- States.filter(s => (s.alpha3Code inSet codes) && s.countryId === countryId).result
        stateTables = statesUtil.map(x => StateTable(0L, x.name, x.alpha3Code, countryId))
        statesInserted <- StatesInsertQuery ++= stateTables.filter(s => !existing.exists(x => x.alpha3Code == s.alpha3Code && x.countryId == s.countryId))
      } yield existing ++ statesInserted
    })

    db.run(interaction.transactionally)
  }

如果我在这里写:

val 交互 = DBIO.sequence(...).扁平化

或这里:

db.run(interaction.flatten.transactionally)

[错误] 无法证明 Seq[Seq[StateRepository.this.StateTableMapping#TableElementType]] <: slick.dbio.dbioaction>

但是当应用程序运行时,因为 IDE 没有将其检测为错误:

我用 DBIO.fold:

更新了我的定义

【问题讨论】:

    标签: scala slick flatten


    【解决方案1】:

    一个可行的解决方案应该是在Future 完成后将序列展平:

    def insertIfNotExists(mapCountryStates: Map[String, Iterable[StateUtil]]): Future[Seq[StateTable]] = {
      val interaction = DBIO.sequence(mapCountryStates.toSeq.map { case (alpha2Country, statesUtil) =>
        val codes = statesUtil.map(_.alpha3Code)
        for {
          countryId <- Countries.filter(_.alpha2Code === alpha2Country).map(_.id).result.head
          existing <- States.filter(s => (s.alpha3Code inSet codes) && s.countryId === countryId).result
          stateTables = statesUtil.map(x => StateTable(0L, x.name, x.alpha3Code, countryId))
          statesInserted <- StatesInsertQuery ++= stateTables.filter(s => !existing.exists(x => x.alpha3Code == s.alpha3Code && x.countryId == s.countryId))
        } yield existing ++ statesInserted
      })
    
      db.run(interaction.transactionally).map(_.flatten)
    }
    

    【讨论】:

    • 那个解决方案是我在返回控制器之前所做的,但是我想在dbioaction中扁平化,无论如何,非常感谢,问候
    【解决方案2】:

    看来您可能在关注DBIO.fold。这提供了一种方法来采取一些行动并将它们减少到一个值。在这种情况下,您的单个值是来自 Seq[Seq[StateTable]]Seq[StateTable]

    这可能看起来如何的草图......

    def insertIfNotExists(...): DBIO[Seq[StateTable]] = {
      val interaction: Seq[DBIO[Seq[StateTable]]] = ...
      val startingPoint: Seq[StateTable] = Seq.empty
      DBIO.fold(interaction, startingPoint) {
        (total, list) => total ++ list
      }
    }
    

    看起来类型将使用折叠排列。希望它对您的情况有所帮助。

    Chapter 4 of Essential Slick 中有更多关于折叠的信息。

    【讨论】:

    • 哎呀,我以前没有意识到,折叠这正是我想要的,感谢@Richard Dallaway,现在如果我关闭我的解决方案......
    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多