2017-02-01 5 views
3

Ich googelte und fand diesen Thread Slick 3.0: Delete rows from multiple tables in a transaction Allerdings sagt die Lösung, dass es keine gute Lösung ist.Löschen von Zeilen aus mehreren Tabellen in einer glatten Abfrage

Ich Löschen von Zeilen aus mehreren Tabellen mit meinem Code unten

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) 

Aber ich frage mich, ob es eine bessere Art und Weise des Schreibens dieser ist.

Mein Problem mit dem obigen Ansatz ist, dass ich die Anzahl der Zeilen aus TabelleA und nicht die Summe der Zeilen aus den untergeordneten Tabellen TableB und TableC gelöscht werden soll.

Auch zur Laufzeit klagt es über die Verknüpfung der Löschabfrage.

+0

ich mit Ansatz irgendwelche Probleme nicht sehen. Es sollte gut funktionieren. Stehen Sie vor spezifischen Problemen beim Löschen der Datensätze? –

+0

die Frage aktualisiert –

Antwort

6

Ich glaube, Sie auch auf diese Weise tun können -

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 
    })) 
    } 
+0

Funktioniert das? Ich denke, Sie führen jede Aktion in ihren eigenen Transaktionen aus. Aber wir müssen alle 3 in einer einzigen Transaktion ausführen. –

+0

Es funktioniert, führt hier 3 Aktionen in einer einzigen Transaktion aus. – Jet

1

Folgendes würde die Join-Warnung/den Joule-Fehler beheben.

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) 

Und da Sie andthen zu Kette Ihre Aktionen verwenden, die zusammengesetzte Aktion würde die Zeile betroffen Zählung der letzten Aktion immer wieder zurückkehren, wie here angegeben. Die zurückgegebene Nummer ist also immer die Zeilen, die aus der Aktion deleteA gelöscht wurden, da dies die letzte Aktion in der andThen-Kette ist.

andthen

Führen Sie eine weitere Aktion nach dieser Aktion, wenn sie erfolgreich abgeschlossen, und geben das Ergebnis der zweite Aktion. Wenn eine der beiden Aktionen fehlschlägt, schlägt die resultierende Aktion ebenfalls fehl.

Verwandte Themen