从灵活查询中的多个表中删除行

Deleting Rows from multiple tables in a slick query

我用谷歌搜索并找到了这个线程Slick 3.0: Delete rows from multiple tables in a transaction但是解决方案说它不是一个好的解决方案。

我正在使用下面的代码从多个表中删除行

val deleteB = for {
  aId <- TableA.filter(a => a.id === param).map(_.id)
  bId <- TableB.filter(_.aId === aId)
} yield bId

val deleteC = for {
  aId <- TableA.filter(a => a.id === param).map(_.id)
  cId <- TableC.filter(_.aId === aId)
} yield cId

val deleteA = TableA.filter(a.Id === param)

val query = (deleteC.delete andThen deleteB.delete andThen deleteA.delete).transactionally
db.run(query)

但是不知道有没有更好的写法

我对上述方法的问题是,我想return 从 TableA 中删除的行数,而不是从子表 TableB 和 TableC 中删除的行的总和。

此外,在运行时它抱怨在删除查询中有连接。

以下将解析联接 warning/error。

val deleteB = TableB.filter(_.aid in TableA.filter(a => a.id === id).map(_.id))

val deleteC = TableC.filter(_.aid in TableA.filter(a => a.id === id).map(_.id))

val deleteA = TableA.filter(_.id === id)

db.run((deleteB.delete andThen deleteC.delete andThen deleteA.delete).transactionally)

并且由于您使用 andThen 来链接您的操作,因此组合操作将始终 return 行影响的最后一个操作的计数 here。因此 returned 数字始终是从 deleteA 操作中删除的行,因为这是 andThen 链中的最后一个操作。

然后

Run another action after this action, if it completed successfully, and return the result of the second action. If either of the two actions fails, the resulting action also fails.

我想你也可以这样做-

 def buildTransactionQuery = {
    for {
      deleteA <- TableA.filter(a.Id === param)
      deleteB  <- TableB.filter(_.aId === deleteA.map(_.id))
      deleteC  <- TableC.filter(_.aId === deleteA.map(_.id))

      deleteAAction = deleteA.delete
      deleteBAction = deleteB.delete
      deleteCAction = deleteC.delete
      res = (deleteAAction, deleteBAction, deleteCAction)
    } yield res
  }

  def executeTransactionQuery = {
    val transactionQuery = for {
      queries <- buildTransactionQuery
      action = DBIOAction.seq(queries._3, queries._2, queries._1)
    } yield action
    transactionQuery.flatMap(action => db.run(action.transactionally).transform(s => true, t => {
      logger.error(t.getMessage)
      t
    }))
  }