Ich arbeite an einem ASP.NET MVC 6-Projekt mit Entity-Framework Core (Version "EntityFramework.Core": "7.0.0-rc1-final"
), das von einer SQL Server 2012-Express-DB unterstützt wird.
Ich muss eine Viele-zu-Viele-Beziehung zwischen einer Entität Person
und einer Entität Address
modellieren.
Nach diesem Leitfaden habe ich es mit einem PersonAddress
beitreten- Tabelleneinheit, weil ich auf diese Weise zusätzliche Informationen speichern kann.
Mein Ziel ist, mein System auf diese Weise einzurichten:
Person
-Instanz gelöscht wird, müssen alle zugehörigen PersonAddress
-Instanzen gelöscht werden. Alle Address
Instanzen, auf die sie verweisen, müssen ebenfalls gelöscht werden, nur wenn sie nicht mit anderen PersonAddress
Instanzen verbunden sind. PersonAddress
-Instanz gelöscht wird, muss die Address
-Instanz, auf die sie sich bezieht, nur gelöscht werden, wenn sie nicht mit anderen PersonAddress
-Instanzen verknüpft ist. Alle Person
Instanzen müssen leben. Address
-Instanz gelöscht wird, müssen alle zugehörigen PersonAddress
-Instanzen gelöscht werden. Alle Person
Instanzen müssen leben. Ich denke, dass die meiste Arbeit in der Viele-zu-Viele-Beziehung zwischen Person
und Address
gemacht werden muss, aber ich erwarte auch etwas Logik zu schreiben. Ich werde diesen Teil aus dieser Frage herauslassen. Was mich interessiert, ist, wie ich meine Viele-zu-Viele-Beziehung konfigurieren kann.
Hier ist die aktuelle Situation .
Dies ist die Entität Person
. Beachten Sie, dass diese Entität Eins-zu-viele-Beziehungen mit anderen sekundären Entitäten hat.
Dies ist die Entität Address
.
Dies ist die Entität PersonAddress
.
Dies ist die Entität DatabaseContext
, in der alle Beziehungen beschrieben sind.
Die beiden Entitäten Telephone
und City
wurden der Einfachheit halber entfernt.
Dies ist der Code zum Entfernen von Person
.
Wie bei meinen Lesungen wird die Vermeidung von .Include()
die DB veranlassen, sich um die eventuellen CASCADE
Löschungen zu kümmern. Es tut mir leid, aber ich erinnere mich nicht an die SO-Frage, wo dieses Konzept geklärt wurde.
Wenn ich diesen Code ausführe, kann ich die DB mit dieser Problemumgehung erstellen. Wenn ich eine Person
Entität mit dem obigen Code testen möchte, bekomme ich diese Ausnahme:
Ich habe mehrere Beziehungseinstellungen in der DatabaseContext.OnModelCreating
Methode ohne Glück getestet.
Zum Schluss, hier ist meine Frage . Wie konfiguriere ich meine Viele-zu-Viele-Beziehung, um ein Person
und die damit verbundenen Entitäten korrekt aus meiner Anwendung zu löschen, entsprechend dem zuvor beschriebenen Ziel ?
Danke euch allen.
Zuerst sehe ich, dass Sie die Beziehung Stadt und Adresse mit DeleteBehavior.Restrict
festgelegt haben und Sie sagen:
' // Ich möchte die Stadt nicht löschen, wenn ich eine Adresse lösche '.
Aber Sie brauchen hier nicht Einschränken, denn auch mit DeleteBehavior.Cascade
City wird nicht gelöscht.
Sie sehen es von der falschen Seite.
Was Cascade
hier tut ist, wenn eine Stadt gelöscht wird, werden alle dazugehörigen Adressen ebenfalls gelöscht.
Und dieses Verhalten ist logisch.
Zweitens ist Ihre Viele-zu-Viele-Beziehung in Ordnung.
Wenn Sie Person löschen, werden die Links von PersonAddress Table automatisch wegen Cascade gelöscht.
Und wenn Sie auch Adressen löschen möchten, die nur mit dieser Person verbunden waren, müssen Sie dies manuell tun.
Sie müssen diese Adressen löschen, bevor Sie die Person löschen, um zu wissen, was gelöscht werden soll.
Also sollte die Logik folgen:
1. Abfrage über den gesamten Datensatz von PersonAddress wo PersonId = person.Id
;
2. Von denen nehmen nur diejenigen, die einzelnes Auftreten von AddressId in der PersonAddress-Tabelle haben, und löschen sie aus Person-Tabelle.
3. Löschen Sie nun die Person.
Sie können dies direkt im Code tun, oder wenn Sie möchten, dass die Datenbank dies für Sie erledigt, könnte der Trigger für Schritt 2 mit der Funktion erstellt werden: Wenn die Zeile von PersonAddress gelöscht werden soll, prüfen Sie, ob in dieser PersonAddress-Tabelle keine Zeilen mehr mit derselben AddressId vorhanden sind. In diesem Fall löschen Sie sie aus der Address-Tabelle.
Weitere Informationen finden Sie hier:
So kaskadieren Sie das Löschen über viele zu viele Tische
Wie lösche ich aus mehreren Tabellen mit INNER JOIN im SQL Server
Tags und Links c# entity-framework ef-code-first code-first entity-framework-core