2017-02-24 5 views
2

Ich will nur ‚Order‘ Wert für beiden Elemente ändern, ich habe den folgenden Code:Entity Framework - neu anordnen Elemente

 int tmpItemOrder = item1.Order; 
     item1.Order = item2.Order; 
     item2.Order = tmpItemOrder; 

     await _db.SaveChangesAsync(); 

aber ich erhalte einzigartiges Schlüsselproblem (Order ist eindeutiger Schlüssel)

{ "Verletzung der UNIQUE KEY Einschränkung 'IX_EscortItems'. Einsatz kann nicht doppelten Schlüssel in Objekt 'dbo.EscortItems'. der doppelte Schlüsselwert (2, 20). \ r \ nDie Anweisung wurde beendet."

}

wie ich verstanden habe, wirft es den Fehler, wenn das System versucht, einen Dubletten Schlüssel selbst innerhalb einer Transaktion zu setzen. Seltsames Verhalten, aber wie es ist.

Wie man dieses Problem richtig löst?

+3

Bei einer Schätzung, wenn die Werte sequenziell aktualisiert werden, sobald die erste gesetzt ist, wird es sofort die eindeutige Schlüsseleinschränkung verletzen. Selbst zwei "SaveChanges" -Rufe haben den gleichen Effekt. Sie müssen wahrscheinlich einen eindeutigen Zwischenwert verwenden. –

+2

Der andere Gedanke ist, dass es ungewöhnlich ist, Schlüssel zu tauschen und vielleicht braucht das Problem einen anderen Ansatz - nur ein Gedanke. –

+0

@PeterSmith, Sie haben Recht, sogar zwei SaveChanges Aufrufe haben den gleichen Effekt! –

Antwort

2

Die eindeutige Einschränkung muss bei jeder Zeile Update nicht nur dann beachtet werden, wenn die Transaktion abgeschlossen ist. Der Versuch, die Zeilen neu anzuordnen, erfordert einen sorgfältigen Algorithmus. Um eine Zeile so zu aktualisieren, dass sie die gewünschte 'Reihenfolge' X hat, müssen Sie zuerst sicherstellen, dass X frei ist (dh, keine Zeile hat bereits diese Reihenfolge). Wenn eine Reihe bereits diese gewünschte Reihenfolge hat, müssen Sie sie aus diesem 'Slot' herausholen, indem Sie sie auf einen 'freien' Wert aktualisieren (ich lasse als Übung für Sie einen solchen 'freien' Wert finden). Wenden Sie dies für jede Zeile an, bevor Sie die 'Bestellung' aktualisieren.

Es wäre viel einfacher, alle Zeilen zu löschen und sie dann wieder in der gewünschten 'Reihenfolge' einzufügen.

Das heißt, es gibt viele Gründe, warum Sie 'Bestellung' in einer Spalte nicht beibehalten möchten. Um nur eines zu nennen, müssen Sie mit Lücken zu tun haben.

+0

Wie dann dieses Problem zu lösen? Einfach verknüpfte Liste? –

+0

Verknüpfte Liste (dh. Eine 'nächste ID' Spalte für jede Zeile halten) ist leicht zu aktualisieren, aber schwer zu * in der Reihenfolge * abzufragen (es sei denn, Sie sind bereit, die Elemente Client-Seite in der App zu sortieren, was ist machbar für kleine Sätze, zB Rechnung oder 'Cart') –

+0

und haben das gleiche Problem zu aktualisieren ... –