我用谷歌搜索并找到了这个帖子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)
但我想知道是否有更好的方式来写这个。
上述方法的问题在于我想返回从TableA中删除的行数,而不是从子表TableB和TableC中删除的行的总和。
此外,在运行时它抱怨在删除查询中加入。
答案 0 :(得分:2)
以下将解决加入警告/错误。
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来链接您的操作,因此组合操作将始终返回上述here的最后一个操作的受影响行数。因此,返回的数字始终是从deleteA
操作中删除的行,因为这是andThen
链中的最后一个操作。
<强> andThen 强>
在此之后运行另一个操作 动作,如果成功完成,并返回结果 第二个动作。如果两个操作中的任何一个失败,则生成 行动也失败了。
答案 1 :(得分:2)
我认为你也可以这样做 -
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
}))
}