Ich habe eine Benutzertabelle und eine Rollentabelle. Es gibt eine automatisch generierte Linsentabelle von UsersRoles, die die ID aus den Tabellen User und Roles enthält. Dies wird mit dem folgenden Code generiert:
%Vor% Wenn ich versuche, eine nicht verwandte Entität hinzuzufügen und Context.SaveChanges()
aufzurufen, erhalte ich den folgenden Fehler:
Verletzung der PRIMARY KEY-Einschränkung 'PK_UsersRoles'. Kann nicht eingefügt werden Schlüssel im Objekt 'dbo.UsersRoles' duplizieren. Der doppelte Schlüsselwert ist (2beaf837-9034-4376-9510-b1609c54efbe, dcd16d00-d46e-4d48-8328-3e7b35b11ccf). Die Aussage wurde beendet.
Ich habe das Conext.ChangeTracker.Entries()
für die im Fehler erwähnten Elemente überprüft und den Entitätsstatus als Unverändert markiert.
Die einzige Entität, die als Hinzugefügt markiert ist, ist der neue Datensatz, den ich hinzufügen möchte, alles andere ist als Unverändert markiert.
Code zum Hinzufügen von Entity:
%Vor%Weiß jemand, warum das passiert?
Die Tatsache, dass User
mit UserId = 2beaf837-9034-4376-9510-b1609c54efbe
und Role
mit RoleId = dcd16d00-d46e-4d48-8328-3e7b35b11ccf
im Zustand Unchanged
sind, bedeutet nicht, dass nichts in die Datenbank geschrieben wird.
Insbesondere für Viele-zu-Viele-Beziehungen (im Allgemeinen für unabhängige Zuordnungen) behält EF einen Zustand für die Beziehung selbst bei, der sich vom Zustand entity unterscheidet. Wenn ein Eintrag in die Verknüpfungstabelle eingefügt wird, bedeutet dies, dass der Beziehungseintrag für die beiden fraglichen Entitäten im Status Added
ist, obwohl der Entitätsstatus für diese Entitäten Unchanged
ist. Sie können den Beziehungseintrag nicht sehen, wenn Sie die DbContext
s ChangeTracker
aufzählen. Es gibt nur Entitätszustände zurück. Sie müssen zum zugrunde liegenden ObjectContext
gehen, um den Beziehungsstatus abzufragen.
Beispiel:
%Vor% Hier werden user
und role
beide im Status Unchanged
sein, aber immer noch wird ein Datensatz in die Link-Tabelle eingefügt. Und dieser Code wird Ihre Ausnahme auslösen, wenn Benutzer 1 und Rolle 5 bereits in der Datenbank verknüpft sind.
Das Hinzufügen von group
hat nichts mit dem Problem zu tun. Nur der Aufruf von SaveChanges
verursacht die Ausnahme, weil Sie wahrscheinlich eine Beziehung zwischen den beiden Entitäten irgendwo vor dem Code-Snippet in Ihrer Frage erstellt haben.
Um zu Slaumas Antwort hinzuzufügen, sieht es so aus, als wenn Sie die ICollection-Eigenschaft auf eines dieser Auto-Viele-zu-Viele-Dinge setzen, wird EF verwirrt und erkennt nicht, dass Sie die Auflistungselemente löschen, indem Sie dies tun / p>
Also anstatt das zu tun:
%Vor%Sie müssen dies tun:
%Vor%Das hat für mich funktioniert.
Sie sollten das allerdings nicht tun müssen. Dies sollte ein Fehler in EF sein.
Sie versuchen, die gleiche Kombination von Benutzer / Rolle in die UserRoles-Tabelle einzufügen:
Violation of PRIMARY KEY constraint 'PK_UsersRoles'. Cannot insert duplicate key in object 'dbo.UsersRoles'. The duplicate key value is (2beaf837-9034-4376-9510-b1609c54efbe, dcd16d00-d46e-4d48-8328-3e7b35b11ccf). The statement has been terminated.
Überprüfen Sie, welcher Benutzer die ID 2beaf837-9034-4376-9510-b1609c54efbe hat und welche Rolle die ID dcd16d00-d46e-4d48-8328-3e7b35b11ccf hat. Wenn Sie sicher sind, dass Sie diesen Benutzer nur einmal eingegeben haben, fügt die Methode die Daten, die aufgerufen werden, mehrmals hinzu, ohne dass Sie dies bemerken?
In der Hoffnung, dass jemand es hilfreich finden wird, habe ich festgestellt, dass es einen großen Unterschied zwischen dem Ändern einer bestehenden Liste in EF im Vergleich zum Erstellen einer neuen Liste gibt.
In diesem Fall habe ich ein Update gemacht und dachte mir, es wäre am einfachsten, einfach eine neue Liste der gewünschten Artikel zu erstellen. Aber wenn einige der Elemente bereits zur Liste hinzugefügt wurden, würde ich beim Speichern eine primäre Schlüsselverletzung bekommen.
Ich habe die selbe Liste behalten und nur Änderungen daran vorgenommen. Löschen und lesen war ok, Erstellen einer neuen Liste war nicht.
Tags und Links .net c# entity-framework ef-code-first