在一个灵活的查询中从多个表中删除行
Posted
技术标签:
【中文标题】在一个灵活的查询中从多个表中删除行【英文标题】:Deleting Rows from multiple tables in a slick query 【发布时间】:2017-02-01 23:25:27 【问题描述】:我用谷歌搜索并找到了这个帖子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 中删除的行数。
此外,在运行时它会抱怨删除查询中有连接。
【问题讨论】:
我没有看到任何方法问题。它应该可以正常工作..您在删除记录时是否遇到任何具体问题? 更新了问题 【参考方案1】:我认为你也可以这样做 -
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
))
【讨论】:
这行得通吗?我认为您正在自己的事务中执行每个操作。但是我们需要在一个事务中运行所有 3 个。 它会工作,在一个事务中执行 3 个操作。【参考方案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
链中的最后一个操作。
然后
在此之后运行另一个操作 动作,如果它成功完成,并返回结果 第二个动作。如果这两个操作中的任何一个失败,则结果 操作也失败了。
【讨论】:
谢谢!这是一个更清洁的解决方案。以上是关于在一个灵活的查询中从多个表中删除行的主要内容,如果未能解决你的问题,请参考以下文章
使用 LINQ 和实体框架在一个 SQL 查询中从多个表中提取数据