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

.net entity-framework sql-server vb.net

Frage

Ich versuche, einen Wert eines zusammengesetzten Primärschlüssels aus dem Entitätsframework heraus zu aktualisieren, und ich erhalte folgende Fehlermeldung: "Die Eigenschaft 'CustomerID' ist Teil der Schlüsselinformationen des Objekts und kann nicht geändert werden."

Hier ist mein Code:

Dim customer As Customer = (From c In db.Customer Where c.CustomerID = "xxx" AndAlso c.SiteKey = siteKey).FirstOrDefault
customer.CustomerID = "fasdfasdf"
db.SaveChanges()

Es scheint zu einfach. Stimmt es, dass Sie keinen Primärschlüssel innerhalb des Entity-Frameworks aktualisieren können? Ich kann keine Dokumentation zu dem Thema finden. Vielen Dank!

Akzeptierte Antwort

Sie können nicht und aus gutem Grund. Siehe KM-Kommentare.

Ich sage, Sie könnten zwei Tabellen haben, eine mit anonymen Daten und eine, in der die realen Benutzerdaten gespeichert werden, nachdem sie sich angemeldet haben.

Oder Sie könnten (nicht von mir getestet oder jemals von mir gemacht) diese Art von Tabellenlayout haben:

---Customers----
AutoNumber PK <- This links to all other tables in your database, and does NOT change.
CustomerID  <- This can change.
CustomerType <- Anonymous or logged in.  

Und wenn sie sich anmelden, ändern Sie den Kundentyp und die Kundennummer entsprechend Ihren Anforderungen.

Ihre Anfrage könnte also so aussehen:

Dim customer As Customer = (From c In db.Customer _
                            Where c.CustomerID = {Some temp ID} _
                            AndAlso c. CustomerType = "Anonymous").FirstOrDefault
// After user logs in.
customer.CustomerID = {Make a new user ID here}
customer.CustomerType = "LoggedIn" {or what ever}
db.SaveChanges()

Beachten Sie, dass sich der Primärschlüssel für die automatische Nummerierung niemals ändert. Dies ist so, dass alle Tabellen, die Sie in einer Beziehung mit der Customers-Tabelle haben, weiterhin funktionieren und keine kaskadierenden Aktualisierungen des Primärschlüssels vornehmen müssen (dies ist, als würden Sie sich mit einem Stift in das Auge stechen).


Beliebte Antwort

Ich habe einen Doktortitel In cs - im Bereich Datenbanken, wird diese Antwort etwas anders sein als in der Perspektive eines Programmierers. Bei allem Respekt für Oliver Hanappi kann und kann sich ein Schlüssel gelegentlich ändern, wenn es sich nicht um einen Ersatzschlüssel handelt. ZB ein natürlicher Schlüssel oder ein zusammengesetzter Schlüssel. Zum Beispiel. Es ist möglich, Ihre SSN in den USA zu ändern. Aber viele Programmierer im Laufe der Jahre würden dies als einen unveränderlichen Schlüssel betrachten und als solchen verwenden. 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 Primärschlüssel in ihren jeweiligen Tabellen sind). Um jedoch die Beziehung zwischen zwei Einheiten zu erhalten , während der dritte Einheit zu ändern erfordert Teil der Kreuzungswicke (auch als reine Tabelle auf MSDN Join) Primärschlüssel. Dies ist ein gültiges Design und könnte nur verbessert werden, indem die Kreuzungstabelle für ternäre Beziehungen entfernt und durch zwei binäre Beziehungstabellen ersetzt wird (die möglicherweise eigene Ersatzschlüssel haben). EF würde damit umgehen. Diese Designänderung würde ein (viele-> viele) -> viele oder Parent1-Parent2 -> Child-Enkel-Modell machen (wenn dies nicht klar ist, lesen Sie das folgende Beispiel). Das Entity-Framework würde gut funktionieren, da jede Beziehung wirklich eine Beziehung zu vielen Beziehungen ist. Aber es ist ein verrücktes Design aus Sicht der DB. Ich zeige Ihnen ein Beispiel warum.

Beachten Sie, dass Kurs, Klassenzimmer und Ausbilder in einer Klasse miteinander verbunden sind. Die Klasse könnte Folgendes enthalten: CourseID, ClassroomID, InstructorID als Fremdschlüssel und einen zusammengesetzten Primärschlüssel, der alle drei enthält. Obwohl es ein klares, kurzes ternäres Modell (3-Wege-Beziehung) ist, könnten wir es in binäre Beziehungen aufteilen. Dies würde zwei Kreuzungstabellen ergeben. Das Hinzufügen von Ersatzschlüsseln würde EF folgendermaßen erfüllen:

Klasse ( SurrogateKeyClass , InstructorID , CourseID )

ClassRoomUsed ( SurrogateKeyClassroomUsed , SurrogateKeyClass , ClassRoomID )

Das Problem bei diesem Design ist, dass wir den gleichen Kurs und Kursleiter mehrmals verwenden können, was das vorherige Modell vermeidet. Um dieses Problem zu vermeiden, können Sie der Eindeutigkeit der beiden ID-Felder eine Einschränkung in der Datenbank hinzufügen. Warum sollten Sie dies jedoch tun, wenn Sie sich nur mit Ersatzschlüsseln befassen? Diese Lösung funktioniert jedoch so gut wie ich kann. Dies ist jedoch kein logischer Datenbankentwurf, da in der Datenbank eine nicht eindeutige eindeutige Einschränkung erforderlich ist.

ABER, wenn Sie Ihre Datenbank nicht ändern möchten oder Ihre Datenbank nicht ändern können, finden Sie hier eine zweite Lösung : Kreuzungs- / Verbindungstabellen sind genau das, Verknüpfungen, die zwei oder mehr Entitäten miteinander verbinden. Wenn Sie sich ändern, 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 anfordern dürfen. Dies ist jedoch äußerst häufig.

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

Ein weiteres Beispiel kostenlos:

Betrachten Sie einen Studenten, einen Kurs, eine Klassenvereinigung. Die Studierenden werden über eine Note mit einem Kurs verbunden. Normalerweise handelt es sich hierbei um eine viel zu viele Zuordnung zwischen einem Schüler und einem Kurs mit einem zusätzlichen Feld in der Zuordnungstabelle, die als grade bezeichnet wird (Zuordnungstabellen haben Nutzdaten wie grade, Kreuzungstabellen haben keine Nutzlast und werden in MSDN als reine Join-Tabellen bezeichnet Leasing an einem Ort):

Student ( StudentID , ....)

Kurs ( KursID , ...)

Einnahme ( StudentID , CourseID , Note)

Wenn jemand aus einer Dropdown-Liste einen Dateneingabefehler macht und einen Schüler in die falsche Klasse versetzt, können Sie ihn später ändern, indem Sie die Dropdown-Liste erneut auswählen und einen anderen Kurs auswählen. Im Hintergrund müssen Sie das EF-Objekt aus der Taking-Tabelle löschen und es neu erstellen, ohne eine Note zu verlieren, falls vorhanden. Die Fremdschlüssel-CourseID einfach zu ändern scheint eine bessere Alternative zu sein. Kommen Sie mit Ihrer eigenen Assoziation, wenn dies scheint, aber als Professor war es für mich selbstverständlich.

Fazit: Wenn Sie eine Reihe von Beziehungen haben, ist es möglicherweise besser, das Kaskadieren und / oder Ändern von FK nicht zuzulassen, aber es gibt vernünftige / logische Szenarien, in denen dies erforderlich ist, auch wenn dies im Allgemeinen nicht empfohlen wird.

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

Eine Verletzung der referentiellen Integritätsbedingung ist aufgetreten: Eine Primärschlüsseleigenschaft, die Teil der Einschränkung der referentiellen Integrität ist, kann nicht geändert werden, wenn das abhängige Objekt nicht geändert wird, es sei denn, es wird auf das Hauptobjekt der Assoziation gesetzt. Das Hauptobjekt muss verfolgt und nicht zum Löschen markiert werden.

Die Eigenschaft 'X' ist Teil der Schlüsselinformationen des Objekts und kann nicht geändert werden.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum