Entity Framework-Kerncode - Zuerst: Überschüssiges Löschen in einer Viele-zu-Viele-Beziehung

8

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:

  • Wenn eine 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.
  • Wenn eine 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.
  • Wenn eine 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.

%Vor%

Dies ist die Entität Address .

%Vor%

Dies ist die Entität PersonAddress .

%Vor%

Dies ist die Entität DatabaseContext , in der alle Beziehungen beschrieben sind.

%Vor%

Die beiden Entitäten Telephone und City wurden der Einfachheit halber entfernt.

Dies ist der Code zum Entfernen von Person .

%Vor%

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:

%Vor%

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.

    
m.phobos 04.03.2016, 15:29
quelle

1 Antwort

0

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

    
borisdj 08.02.2017, 08:54
quelle