Laden...

Verknüpfte Einträge in der Datenbank ebenfalls löschen: CascadeOnDelete funkt. nicht

Erstellt von Christoph1968 vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.218 Views
C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 5 Jahren
Verknüpfte Einträge in der Datenbank ebenfalls löschen: CascadeOnDelete funkt. nicht

Hallo Community,

es ist mir echt peinlich, aber ich kriege das folgende Problem,
ein simples CascadeOnDelete im EntityFramework (CodeFirst)
einfach nicht gelöst:

Diese abstrakte Basisklasse wird an alle relevanten Entities der Anwendung vererbt. Sie beinhaltet die ID jedes Objektes.
In der Datenbank erscheint damit in jeder Tabelle eine Id(PK,FK, uniqueidentifier, notNull) und in der Tabelle MetaData eine Zeile für jede
Entity, egal welcher abgeleiteter Klasse. MetaData speichert diverse Indikatoren, ob ein Objekt gerade editiert wird,
wann und von wem es zuletzt gepeichert wurde, usw. um die Zugriffsprobleme im MultiUser-Betrieb zumindest halbwegs in den Griff zu kriegen.

 
[Table("MetaData")]
[Serializable]
public abstract class MetaData : INotifyPropertyChanged
{
	[Key]
	public Guid Id { get; set; }
	....
}  

Das Scenario, um das es geht ist folgendes:

 
[Table("CompanySites")]
 [Serializable]
public class CompanySite : MetaData
 {
     ...
     private ObservableCollection<CompanySiteRoleType> _companySiteRoleTypes;
     public virtual ObservableCollection<CompanySiteRoleType> CompanySiteRoleTypes
	{
		get
		{
			return _companySiteRoleTypes;
		}
		set
		{
			if (_companySiteRoleTypes != value)
			{
				_companySiteRoleTypes = value;
				SetPropertyChanged();
			}
		}
	}
 ...  
 }//public class CompanySite : MetaData
 
 
[Table("CompanySiteRoleTypes")]
[Serializable]
public class CompanySiteRoleType : MetaData
{
	...
	public Guid CompanySiteId { get; set; }
    private CompanySite _companySite;
    [ForeignKey("CompanySiteId")]
    [Index("CompanySiteIdAndCompanyRoleType", 1)]
	public virtual CompanySite CompanySite
	{
		get
		{
			return _companySite;
		}
		set
		{
			if (_companySite != value)
			{
				_companySite = value;
				SetPropertyChanged();
			}
		}
	}
	...
}//public class CompanySiteRoleType : MetaData

Was ich will ist, dass wenn ein Objekt vom Typ CompanySite gelöscht wird, alle dieser Instanz über die ObservableBindingCollection
zugeordneten Objekte vom Typ CompanySiteRoleType ebenfalls gelöscht werden.

Wenn ich mich so umsehe, sollte dieses Verhalten wohl eigentlich sogar standardmäßig so sein.
Aber leider Fehlanzeige. Im SQL-Studio sehe ich den ForeignKey in den CompanySiteRoleTypes korrekt abgebildet, aber die DeleteRule ist immer "NoAction".

Auch wenn ich im modelBuilder folgende Zeile angebe, ändert dies leider nichts:



modelBuilder.Entity<CompanySite>().HasMany(i => i.CompanySiteRoleTypes).WithRequired(i => i.CompanySite).WillCascadeOnDelete(true);


Nun meine Frage: Kann es sein, dass die Basisfunktionalität "CascadeOnDelete" durch meine Konstruktion mit der abstakten Basisklasse "MetaData" ausgehebelt wird?

Ich weiß, dass man das alles alles auch "händisch" durch Iteration durch die Liste und manuelles Löschen der betroffenen Entities erreichen kann,
aber ich kann und will nicht glauben, dass es für dieses banale Problem, das vermutlich zigfach in jeder Datenbankanwendung erforderlich ist,
keine andere Lösung gibt.

Viele Grüße und vielen Dank Euch !!

Christoph

5.658 Beiträge seit 2006
vor 5 Jahren

Die Models für den EF sollten reine "POCOs" (Plain old CLR objects) sein, also keinerlei Logik (wie z.B. INotifyPropertyChange) enthalten. Die Logik gehört in die BL, und die Logik der Benutzeroberfläche in ein ViewModel o.ä.

Weeks of programming can save you hours of planning

16.842 Beiträge seit 2008
vor 5 Jahren

.. und verzichte auf die Attribute in EF und verwende Fluent Code für die Modellierung.
Von einem Mix, wie Du es hast, wird ausdrücklich abgeraten.

Zum Trennung von Klassen:
[Artikel] Drei-Schichten-Architektur

C
Christoph1968 Themenstarter:in
93 Beiträge seit 2007
vor 5 Jahren

Hallo Abt, hallo MrSparkle,

vielen Dank für Eure Antworten.

Ich ziehe daraus den folgenden Schluß:

Prinzipiell steht das Konstrukt mit der abgeleiteten Basisklasse
nicht im Widerspruch zu CascadeOnDelete.

Ich habe nur ein paar Dinge falsch angepackt.

Ich werde nun versuchen, die von Euch vorgeschlagene Trennung
zwischen Modellierung und Daten umzusetzen.

Vielen Dank nochmals und viele Grüße

Christoph