2012-06-27 8 views
6

Beim Löschen einer Datensatzgruppe werden nur die Zeilen ungerade gelöscht!Warum löscht diese ScalaQuery-Anweisung nur die ungeraden Zeilen?

val byUser = Orders.createFinderBy(_.userID) 
byUser(id).mutate(_.delete) 

Wenn ich stattdessen den Datensatz drucke, bekomme ich die richtige Anzahl von Zeilen.

byUser(id).mutate{x => x.echo} 

Ich arbeitete um das Problem so, das die gewünschte SQL generiert.

(for{o <- Orders if o.userID is id.bind } yield o).delete 

Aber warum oder wie beeinflusst die mutierte Version nur die ungeraden Zeilen?

+5

Obwohl ich nicht weiß, was in diesem speziellen Fall passiert, ist es ein sehr häufiges Problem mit verknüpften Listen: Wenn Sie versuchen, zu löschen Während des Iterierens löschen Sie einen, dann iterieren Sie einen, löschen dann einen usw., so dass die Hälfte Ihrer Liste übrig bleibt. Jeder Iterator in einer änderbaren Auflistung kann unter diesem Problem leiden, je nachdem, wie er erstellt wurde. Ich weiß nicht, welche alternativen Strategien Ihnen hier zur Verfügung stehen - bei verknüpften Listen lösen Sie das Problem, indem Sie nur löschen und die Löschungen selbst durch die gesamte Liste iterieren lassen. –

+0

@RexKerr muss etwas ähnlich zu dem sein, was Sie beschreiben. Die Alternative besteht darin, eine Abfrage zu erstellen, die nicht MutatingUnitInvoker aufruft (die Art der Abfrage, die von vorbereiteten Anweisungsausdrücken wie createFinderBy und für Ausdrücke, die über Parameter [T] binden, generiert wird) – virtualeyes

+0

@RexKerr Es sieht so aus, als hätten Sie die einzige Antwort, I würde es als solche posten und einige Stimmen bekommen :) –

Antwort

1

Ich habe im Quellcode gegraben und es scheint so zu sein, wie @RexKerr sagt - ein Iterator wird verwendet, um die Elemente zu verarbeiten, die Löschungen anwenden, während es iteriert (die while-Schleife in der Mutate-Methode) :

https://github.com/rjmac/scala-query/blob/master/src/main/scala/org/scalaquery/MutatingInvoker.scala

Interessanterweise gibt es eine previousAfterDelete flag, das verwendet werden kann, den Iterator zu zwingen, nach hinten nach jedem Löschvorgang. Dies scheint für Access-Datenbanken (siehe AccessQueryInvoker Klasse), andere aber nicht auf true gesetzt werden:

https://github.com/rjmac/scala-query/blob/master/src/main/scala/org/scalaquery/ql/extended/AccessDriver.scala

Ich würde empfehlen, die Quellen herunterladen und den Code debuggen. Vielleicht sollte dieses Flag für den Datenbankanbieter festgelegt werden, den Sie verwenden. Ich würde auch prüfen, einen Fehlerbericht Einreichung:

http://scalaquery.org/community.html

PS. Ich weiß, das ist eine alte Frage, aber beantwortet, nur für den Fall, dass jemand anderes dieses Problem hatte

+0

Die Community hat sich längst auf die nächste Version der Bibliothek, Slick, verlegt, aber ich habe noch ein Projekt auf SQ, also danke für die lang erwartete Antwort ;-) – virtualeyes

Verwandte Themen