Удаление строк из нескольких таблиц в скользком запросе
Я погуглил и нашел эту тему Slick 3.0: удаление строк из нескольких таблиц в транзакции. Однако решение говорит, что это не очень хорошее решение.
Я удаляю строки из нескольких таблиц с моим кодом ниже
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.
Кроме того, во время выполнения он жалуется на наличие соединений в запросе на удаление.
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
}))
}
Следующее исправит предупреждение о соединении / ошибка.
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 для цепочки своих действий, составленное действие всегда будет возвращать количество затронутых строк последнего действия, как указано здесь. Таким образом, возвращаемое число - это всегда строки, удаленные из deleteA
действие, так как это последнее действие в andThen
цепь.
а потом
Запустите другое действие после этого действия, если оно успешно выполнено, и верните результат второго действия. Если одно из двух действий завершается неудачей, полученное в результате действие также не выполняется.