从灵活查询中的多个表中删除行
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
}))
}
我用谷歌搜索并找到了这个线程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
}))
}