【问题标题】:Conditionally running Slick statements in a for comprehension在 for 理解中有条件地运行 Slick 语句
【发布时间】:2018-03-27 07:59:27
【问题描述】:

给定以下 Slick 代码:

   val doUpdate = true

   val table1 = TableQuery[Table1DB]
   val table2 = TableQuery[Table2DB]
   val table3 = TableQuery[Table3DB]

   val action = (for {
          _ <- table1.filter(_.id === id).update(table1Record)
          _ <- table2.filter(_.id === id).update(table2Record)
          _ <- table3.filter(_.id === id).update(table3Record)
     } yield ()).transactionally

只有当变量 doUpdate 为真时,我才需要更新 table2table3。这是我的尝试:

   val action = (for {
          _ <- table1.filter(_.id === id).update(table1Record)
          _ <- table2.filter(_.id === id).update(table2Record)
               if (doUpdate == true)
          _ <- table3.filter(_.id === id).update(table3Record)
               if (doUpdate == true)
     } yield ()).transactionally

这可以编译,但是当我运行它时,我收到以下错误Action.withFilter failed。如何添加条件?

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    正如您所注意到的,如果您在 for 内使用 if,它将在下面调用 withFilter。在管道(DBIOFutures、Tasks)的情况下,过滤归结为是继续使用管道(快乐路径)还是失败(生成 Failure 或类似的)。

    如果您只想更新,那么您可以选择if 并恢复Future。但是,这会很丑陋,因为根据您编写 case 的方式,它也可能会从您希望了解的错误中恢复。

    替代方案是简单地使用 if-else 来提供不同的DBIOAction

    (for {
      _ <- {
        if (doUpdate) conditionalAction.map(_ => ())
        else DBIOAction.successful(())
      }
    } yield ()).transactionally
    

    在你的情况下,它可能看起来像:

    val action = (for {
      _ <- table1.filter(_.id === id).update(table1Record)
      _ <- {
        if (doUpdate) DBIOAction.seq(
          table2.filter(_.id === id).update(table2Record),
          table3.filter(_.id === id).update(table3Record)
        )
        else DBIOAction.successful(())
      }
    } yield ()).transactionally
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 2014-08-30
      • 1970-01-01
      相关资源
      最近更新 更多