Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Aktualisieren Sie den Primärschlüsselwert mithilfe des Entitätsframeworks

Ich habe einen Ph.D. in cs - im Bereich Datenbanken, daher wird diese Antwort etwas anders sein als die Perspektive eines Programmierers. Bei allem Respekt vor Oliver Hanappi, ein Schlüssel kann und wird sich gelegentlich ändern, wenn es sich nicht um einen Ersatzschlüssel handelt. Z.B. Ein natürlicher Schlüssel oder ein zusammengesetzter Schlüssel. Zum Beispiel. Es ist möglich, Ihre SSN in den USA ändern zu lassen. Aber viele Programmierer hielten dies im Laufe der Jahre für einen unveränderlichen Schlüssel und benutzten ihn als solchen. Es ist viel üblicher, einen zusammengesetzten Primärschlüssel zu ändern, der aus Fremdschlüsseln besteht.

Ich habe es mit einer Datenbank zu tun, die eine ternäre Beziehung hat. Insbesondere drei Entitäten (wobei Fremdschlüssel Ersatz-Primärschlüssel in ihren jeweiligen Tabellen sind). Um jedoch die Beziehung zwischen zwei Entitäten beizubehalten, während die dritte Entität geändert wird, erfordert Ändern eines Teils des Primärschlüssels der Schnittpunkttabelle (auf MSDN auch als reine Join-Tabelle bezeichnet). Dies ist ein gültiges Design und könnte nur verbessert werden, indem die ternäre Beziehungsschnitttabelle entfernt und durch zwei binäre Beziehungstabellen ersetzt wird (die möglicherweise ihre eigenen Ersatzschlüssel haben). EF würde dies gut handhaben. Diese Designänderung würde ein (Viele->viele)->viele oder Eltern1-Eltern2 -> Kind-Enkelkind-Modell machen (wenn das nicht klar ist, lesen Sie das Beispiel unten). Das Entity-Framework würde damit gut funktionieren, da jede Beziehung wirklich eine Eins-zu-Viele-Beziehung ist. Aber es ist ein verrücktes Design aus DB-Sicht. Lassen Sie mich Ihnen ein Beispiel zeigen, warum.

Beachten Sie, dass Course, Classroom und Instructor in einer Klasse miteinander verknüpft sind. Die Klasse könnte Folgendes enthalten:CourseID, ClassroomID, InstructorID als Fremdschlüssel und einen zusammengesetzten Primärschlüssel enthalten, der alle drei enthält. Obwohl es sich um ein klares, prägnantes ternäres Modell (3-Wege-Beziehung) handelt, könnten wir es in binäre Beziehungen aufteilen. Dies würde zwei Schnitttabellen ergeben. Das Hinzufügen von Ersatzschlüsseln würde EF wie folgt erfüllen:

Klasse(SurrogateKeyClass , Dozenten-ID , Kurs-ID )

ClassRoomUsed(SurrogateKeyClassroomUsed , Ersatzschlüsselklasse , Klassenraum-ID )

Das Problem bei diesem Design ist, dass wir den gleichen Kurs und Ausbilder mehrmals zugeordnet haben könnten, was das vorherige Modell vermeidet. Um dieses Problem zu vermeiden, können Sie in der Datenbank eine Einschränkung für die Eindeutigkeit der beiden ID-Felder hinzufügen, aber warum sollten Sie dies tun, wenn Sie es zunächst nur mit Ersatzschlüsseln zu tun haben? Diese Lösung würde jedoch so gut funktionieren, wie ich sagen kann. Dies ist jedoch kein logischer Datenbankentwurf wegen der unnatürlichen Eindeutigkeitsbeschränkung, die in der DB erforderlich ist.

ABER, wenn Sie Ihre Datenbank nicht ändern möchten oder nicht ändern können, hier ist eine zweite Lösung :Schnitt-/Assoziationstabellen sind genau das, Links, die zwei oder mehr Entitäten miteinander verbinden. Wenn sich eine ändert, löschen Sie die Zuordnung und erstellen Sie eine neue mit den entsprechenden Fremdschlüsseln (Navigationseigenschaften). Das bedeutet, dass Sie in keiner der Beziehungen untergeordnete Entitäten verlangen dürfen, aber das ist sehr häufig.

Ich würde vorschlagen, dass das Entity Framework (in Zukunft) denen von uns, die ein elegantes DB-Modell entwerfen können, erlaubt, Teile von Schlüsseln in Schnittmengen-/Assoziationstabellen zu ändern, wenn wir wollen!

Ein weiteres kostenloses Beispiel:

Betrachten Sie eine Schüler-, Kurs- und Notenzuordnung. Die Zuordnung der Studierenden zu einem Kurs erfolgt über eine Note. Normalerweise ist dies eine Viele-zu-Viele-Zuordnung zwischen Student und einem Kurs mit einem zusätzlichen Feld in der Zuordnungstabelle namens Note (Zuordnungstabellen haben Nutzlastdaten wie Note, Schnittpunkttabellen haben keine Nutzlast und werden in MSDN als reine Join-Tabellen bezeichnet at Lease an einem Ort):

Student(StudentID , ....)

Kurs (Kurs-ID , ...)

Unter (StudentID , Kurs-ID , Klasse)

Wenn jemand in einem Dropdown-Menü einen Fehler bei der Dateneingabe macht und einen Schüler in die falsche Klasse einordnet, möchten Sie, dass er dies später ändert, indem er das Dropdown-Menü erneut auswählt und einen anderen Kurs auswählt. Im Hintergrund müssen Sie das EF-Objekt aus der Aufnahmetabelle löschen und neu erstellen, ohne eine Note zu verlieren, falls vorhanden. Ändern Sie einfach den Fremdschlüssel CourseID scheint eine bessere Alternative zu sein. Denken Sie sich Ihre eigene Assoziation aus, wenn diese gekünstelt wirkt, aber als Professor war es für mich selbstverständlich.

Fazit:Wenn Sie eine Reihe von Beziehungen haben, ist es möglicherweise besser, Kaskadierung und/oder Änderung von FK nicht zuzulassen, aber es gibt vernünftige/logische Szenarien, in denen dies erforderlich ist, auch wenn dies nicht als Best Practice allgemein .

Dieses Problem kann sich mit den folgenden Ausnahmen manifestieren, je nachdem, ob Sie die Navigationseigenschaft bzw. die Schlüsseleigenschaft im Modell ändern:

Es ist eine Verletzung der Einschränkung der referenziellen Integrität aufgetreten:Eine Primärschlüsseleigenschaft, die Teil der Einschränkung der referenziellen Integrität ist, kann nicht geändert werden, wenn das abhängige Objekt unverändert ist, es sei denn, es wird auf das Hauptobjekt der Zuordnung festgelegt. Das Hauptobjekt muss nachverfolgt und nicht zum Löschen markiert werden.

Die Eigenschaft 'X' gehört zu den Schlüsselinformationen des Objekts und kann nicht geändert werden.