Ich habe mich gefragt, ob jemand eine gute Lösung für ein Problem hat, auf das ich in den letzten Jahren mehrfach gestoßen bin.
Ich habe einen Einkaufswagen und mein Kunde fordert ausdrücklich, dass seine Bestellung von Bedeutung ist. Also muss ich die Reihenfolge zur DB beibehalten.
Der naheliegende Weg wäre, einfach ein OrderField einzufügen, in das ich N die Nummer 0 zuweisen und auf diese Weise sortieren würde.
Aber dies würde die Nachbestellung erschweren und ich habe irgendwie das Gefühl, dass diese Lösung irgendwie zerbrechlich ist und eines Tages auf mich zurückkommen wird.
(Ich verwende C # 3,5 mit NHibernate und SQL Server 2005)
Vielen Dank
quelle
Ok, hier ist meine Lösung, um die Programmierung für alle zu vereinfachen, die mit diesem Thread arbeiten. Der Trick besteht darin, alle Auftragsindizes über oder unter einem Einfügen / Löschen in einem Update zu aktualisieren.
Verwenden einer numerischen Spalte (Ganzzahl) in Ihrer Tabelle, die von den SQL-Abfragen unterstützt wird
CREATE TABLE myitems (Myitem TEXT, id INTEGER PRIMARY KEY, orderindex NUMERIC);
So löschen Sie den Artikel bei orderindex 6:
DELETE FROM myitems WHERE orderindex=6; UPDATE myitems SET orderindex = (orderindex - 1) WHERE orderindex > 6;
So tauschen Sie zwei Elemente (4 und 7) aus:
UPDATE myitems SET orderindex = 0 WHERE orderindex = 4; UPDATE myitems SET orderindex = 4 WHERE orderindex = 7; UPDATE myitems SET orderindex = 7 WHERE orderindex = 0;
dh 0 wird nicht verwendet, verwenden Sie es also als Dummy, um ein mehrdeutiges Element zu vermeiden.
So fügen Sie bei 3 ein:
UPDATE myitems SET orderindex = (orderindex + 1) WHERE orderindex > 2; INSERT INTO myitems (Myitem,orderindex) values ("MytxtitemHere",3)
quelle
Die beste Lösung ist eine doppelt verknüpfte Liste . O (1) für alle Operationen außer der Indizierung. Nichts kann SQL schnell indizieren, außer einer where-Klausel für das gewünschte Element.
0,10,20 Typen scheitern. Sequenzspalten schlagen fehl. Die Float-Sequenzspalte schlägt bei Gruppenbewegungen fehl.
Die doppelt verknüpfte Liste ist dieselbe Operation zum Hinzufügen, Entfernen, Löschen von Gruppen, Hinzufügen von Gruppen und Verschieben von Gruppen. Einzelne verknüpfte Liste funktioniert auch in Ordnung. Double Linked ist meiner Meinung nach mit SQL besser. Für eine einzelne verknüpfte Liste muss die gesamte Liste vorhanden sein.
quelle
Wie wäre es mit einer Implementierung einer verknüpften Liste? Mit einer Spalte enthält der Wert (Bestellnummer) des nächsten Artikels. Ich denke, es ist bei weitem am einfachsten zu verwenden, wenn Bestellungen dazwischen eingefügt werden. Keine Umnummerierung erforderlich.
quelle
Leider gibt es dafür kein Wundermittel. Sie können die Reihenfolge einer
SELECT
Erklärung NICHT OHNE eine Bestellung nach Klausel garantieren . Sie müssen die Spalte hinzufügen und um sie herum programmieren.Ich weiß nicht, dass ich empfehlen würde, Lücken in der Reihenfolge der Reihenfolge hinzuzufügen. Abhängig von der Größe Ihrer Listen und den Treffern auf der Website können Sie möglicherweise nur sehr wenig für den Overhead-Umgang mit der Logik gewinnen (den Sie noch benötigen würden) für den Anlass, dass alle Lücken aufgebraucht sind). Ich würde genau hinschauen, um zu sehen, welche Vorteile dies für Sie in Ihrer Situation bringen würde.
Entschuldigung, ich kann nichts Besseres anbieten. Ich hoffe, das hat geholfen.
quelle
Ich würde den Ansatz A, AA, B, BA, BB überhaupt nicht empfehlen. Es ist eine Menge zusätzlicher Verarbeitung erforderlich, um die Hierarchie zu bestimmen, und das Einfügen von Einträgen dazwischen macht überhaupt keinen Spaß.
Fügen Sie einfach ein OrderField hinzu, eine Ganzzahl. Verwenden Sie keine Lücken, da Sie dann entweder mit einem nicht standardmäßigen 'Schritt' bei Ihrer nächsten mittleren Einfügung arbeiten müssen, oder Sie müssen zuerst Ihre Liste neu synchronisieren und dann einen neuen Eintrag hinzufügen.
0 ... N zu haben ist einfach neu zu ordnen. Wenn Sie Array-Methoden oder List-Methoden außerhalb von SQL verwenden können, um die Sammlung als Ganzes neu zu ordnen, aktualisieren Sie jeden Eintrag, oder Sie können herausfinden, wo Sie ihn einfügen. und +1 oder -1 für jeden Eintrag danach oder davor entsprechend.
Sobald Sie eine kleine Bibliothek dafür geschrieben haben, wird es ein Kinderspiel.
quelle
Ich würde einfach ein Bestellfeld einfügen. Es ist der einfachste Weg. Wenn der Kunde die Felder nachbestellen kann oder Sie sie in die Mitte einfügen müssen, schreiben Sie einfach die Bestellfelder für alle Artikel in diesem Stapel neu.
Wenn Sie diese Einschränkung später aufgrund der schlechten Leistung bei Einfügungen und Aktualisierungen feststellen, können Sie anstelle einer Ganzzahl ein Varchar-Feld verwenden. Dies ermöglicht ein recht hohes Maß an Präzision beim Einsetzen. Zum Einfügen zwischen den Elementen 'A' und 'B' können Sie beispielsweise ein Element einfügen, das als 'AA' bestellt wurde. Dies ist jedoch mit ziemlicher Sicherheit ein Overkill für einen Einkaufswagen.
quelle
Z
Ihrer Varchar-Feldsortierung?Auf einer Abstraktionsebene über dem Warenkorb können Sie beispielsweise CartOrder (mit CartItem 1-n) ein Feld namens itemOrder verwalten, das nur eine durch Kommas getrennte Liste der ID (PK) der relevanten cartItem-Datensätze sein kann. Auf der Anwendungsebene müssen Sie dies analysieren und Ihre Artikelmodelle entsprechend anordnen. Das große Plus für diesen Ansatz liegt im Fall von Umbesetzungen der Reihenfolge. Möglicherweise werden keine Änderungen an einzelnen Objekten vorgenommen. Da die Reihenfolge jedoch als Indexfeld in den Zeilen der Auftragselementtabelle beibehalten wird, müssen Sie für jedes der Objekte einen Aktualisierungsbefehl ausgeben Zeilen, die ihr Indexfeld aktualisieren. Bitte teilen Sie mir Ihre Kritik an diesem Ansatz mit. Ich bin gespannt, auf welche Weise dies fehlschlagen könnte.
quelle
Ich habe es pragmatisch so gelöst :
Die Reihenfolge wird in der Benutzeroberfläche definiert.
Das Backend erhält eine POST-Anforderung, die die IDs und die entsprechende Position jedes Elements in der Liste enthält.
Ich starte eine Transaktion und aktualisiere die Position für jede ID.
Getan.
Die Bestellung ist also teuer, aber das Lesen der bestellten Liste ist super günstig.
quelle
Ich würde empfehlen, Lücken in der Bestellnummer zu halten. Verwenden Sie also anstelle von 1,2,3 usw. 10,20,30 ... Wenn Sie nur einen weiteren Artikel einfügen müssen, können Sie ihn auf 15 setzen, anstatt alles neu zu ordnen an diesem Punkt.
quelle
Nun, ich würde sagen, die kurze Antwort lautet:
Erstellen Sie einen Primärschlüssel für die Autoidentität in der Tabelle "cartcontents" und fügen Sie die Zeilen in der richtigen Reihenfolge von oben nach unten ein. Wenn Sie dann aus der Tabelle mit der Reihenfolge nach der Autoidentitätsspalte des Primärschlüssels auswählen, erhalten Sie dieselbe Liste. Auf diese Weise müssen Sie alle Artikel löschen und bei Änderungen am Warenkorbinhalt wieder einlegen. (Aber das ist immer noch eine ziemlich saubere Methode.) Wenn dies nicht möglich ist, gehen Sie zur Bestellspalte, wie von anderen vorgeschlagen.
quelle
Wenn ich a verwende
Hibernate
und die Reihenfolge von a speichern muss@OneToMany
, verwende ich aMap
und nicht aList
.@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL) @MapKey(name = "position") @OrderBy("position") private Map<Integer, RuleAction> actions = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this }));
In diesem Java-Beispiel
position
handelt es sich um eine Integer-Eigenschaft,RuleAction
sodass die Reihenfolge auf diese Weise beibehalten wird. Ich denke in C # würde dies ziemlich ähnlich aussehen.quelle