[Entity Framework] Rekursives löschen von Entitäten

  • C#

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    [Entity Framework] Rekursives löschen von Entitäten

    Hallo,

    ich habe Probleme damit Entitäten in meiner Software zu löschen, da diese recht stark verknüpft sind.
    Wenn ich z.B. eine Vorlage lösche, dann muss auch das dazugehörige layout, die LayoutPositionen dieses Layouts und das Dokument soll zwar nicht gelöscht werden, aber das Layout und die Vorlage soll auf null gehen.

    Wenn ich z.B. ein Feld lösche, dann soll das DokumentenFeld das dieses Feld beinhaltet auf null gehen usw.... muss ich das alles per Hand programmieren, oder hilft mir da EF?
    Mir ist klar, dass es cascade delete gibt, aber ich möchte ja nicht immer alles gleich löschen, sondern verschiedene "operationen" vornehmen mal löschen, mal den FK auf null setzten usw...


    Ich habe folgende Models:

    C#-Quellcode

    1. public class Vorlage
    2. {
    3. public int Id { get; set; }
    4. public Layout Layout { get; set; }
    5. }
    6. public class Layout
    7. {
    8. public int Id { get; set; }
    9. public ICollection<LayoutPosition> LayoutPositionen { get; set; }
    10. public Vorlage Vorlage { get; set; }
    11. }
    12. public class LayoutPosition
    13. {
    14. public int Id { get; set; }
    15. public Feld Feld { get; set; }
    16. public Layout Layout { get; set; }
    17. }
    18. public class Feld
    19. {
    20. public int Id { get; set; }
    21. public virtual ICollection<Text> Texte { get; set; }
    22. }
    23. class Dokument
    24. {
    25. public int Id { get; set; }
    26. public Layout Layout { get; set; }
    27. public Vorlage Vorlage { get; set; }
    28. public virtual ICollection<DokumentenFeld> DokumentenFelder { get; set; }
    29. }
    30. class DokumentenFeld
    31. {
    32. public int Id { get; set; }
    33. public Dokument Dokument { get; set; }
    34. public Feld Feld { get; set; }
    35. public int ItemId { get; set; }
    36. }
    Hallo

    @windowsfan, ich weis nicht wie oft ich dir den Link zur EF Core Doku bereits verlinkt habe aber langsam solltest du dort mal anfangen zu lesen.
    Du wirst hier noch zig Thread aufmachen müssen und dich immer wieder ärgern wenn du nicht bald damit anfängst EF zu lernen.
    EF und EF Core sind relativ große Werkzeuge, die es gilt zu verstehen.

    Hier der Link nun für CascadeDelete. Alle wunderbar beschrieben.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo @Nofear23m,

    ich hab die Doku auch gelesen, aber die DOku ist eben nicht für meinen speziellen Fall ausgelegt, bzw. find ich alleine folgende Zeile verwirrend..

    C#-Quellcode

    1. // HasRequired(a > a.Layout) = Die Entität Vorlage muss ein Layout haben .......... WIthRequiredDepent heißt dann was?
    2. modelBuilder.Entity<Vorlage>().HasRequired(a => a.Layout).WithRequiredDependent().WillCascadeOnDelete(true);


    Wenn ich das ganze so mache und eine Vorlage lösche wird zwar die Vorlage und das dazugehörige Layout gelöscht, jedoch erhalte ich folgenden Fehler:

    C#-Quellcode

    1. // Cascading festlegen
    2. modelBuilder.Entity<Vorlage>().HasRequired(a => a.Layout).WithRequiredDependent().WillCascadeOnDelete(true);
    3. modelBuilder.Entity<Layout>().HasOptional(a => a.Vorlage).WithOptionalDependent().WillCascadeOnDelete(true);
    4. // Vorlage löschen
    5. using (WFCDbContext db = new WFCDbContext())
    6. {
    7. Vorlage v = db.Vorlagen.Find(this.Id);
    8. File.Delete(this.Path);
    9. db.Vorlagen.Remove(v);
    10. db.SaveChanges();
    11. }


    Der Code löscht die VOrlage und setzt im Layout der Vorlage die Vorlage_Id auf null. Das Layout sollte aber gelöscht werden...
    Hallo

    Ist das nicht auch das was passieren soll? Wenn die Id "rausfliegt" ist die Referenz weg. Wenn EF das Layout mitlöschen würde wäre das eher schlecht. Du hast ja im Layout auch Referenzen zu X Layoutpositionen, die müssen ja auch noch gelöscht werden. Alsi ich persönlich will mich da nicht auf die Intelligenz eines O/R Mappers verlassen.

    Willst du das Layout auch löschen musst du erstmal die Layoutpositionen auf null setzen und dann löschen. Evtl. musst du die Layoutpositionen auch löschen, ich weis nicht ob du die dann noch benötigst.

    Ich hoffe zumindest das ich das was du vorhast richtig verstanden habe.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Nofear23m schrieb:

    Wenn EF das Layout mitlöschen würde wäre das eher schlecht.
    Dassis wohl Ansichtssache.
    Ich zB liebe dieses Datenbank-Feature, namens "Löschweitergabe".
    Vereinfacht vieles ungemein.
    Auf "Löschweitergabe" spielt wohl auch Mono an, ohne aber konkrete Hinweise zu geben, wie man nu bei EfCore für eine bestimmte Relation die Löschweitergabe einrichtet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ja die das layout sollte auch gelöscht werden. Layoutpositionen gehören auch gelöscht, aber erstmal wollte ich das ganze soweit bringen, dass mal zumindest das layout gelöscht wird... btw. bei dem kleinen test den ich aktuell mache
    habe ich nur eine vorlage und ein layout ohne layoutpositionen....
    layout, Layoutpositionen...
    ähm - ich bin jetzt nicht so sehr in deim Datenmodell drinne, aber ist ja logisch, dass man nicht einfach ein Layout löschen kann, wenn da LayoutPosition-Datensätze herumfahren, die auf das zu löschende Layout per ForeignKey noch verweisen.

    Ausser man hat Löschweitergabe eingerichtet.
    Hallo

    Wir könnten uns das ja für dich ansehen aber ich muss gestehen das ich jetzt keine Lust habe ein Projekt zu reproduzieren.

    Lade doch ein Beispielprojekt hoch und wir sehen uns das mal an.

    Grüße
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hmm - wenn ich mir das angucke:

    windowsfan schrieb:

    C#-Quellcode

    1. // Cascading festlegen
    2. modelBuilder.Entity<Vorlage>().HasRequired(a => a.Layout).WithRequiredDependent().WillCascadeOnDelete(true);
    3. modelBuilder.Entity<Layout>().HasOptional(a => a.Vorlage).WithOptionalDependent().WillCascadeOnDelete(true);
    4. // Vorlage löschen
    5. using (WFCDbContext db = new WFCDbContext())
    6. {
    7. Vorlage v = db.Vorlagen.Find(this.Id);
    8. File.Delete(this.Path);
    9. db.Vorlagen.Remove(v);
    10. db.SaveChanges();
    11. }
    Dann sieht mir das aus, als sei eine Relation Vorlage->Layout erfolgreich konfiguriert, auch mit Löschweitergabe (so sieht mir jdfs. der Code aus).
    Wenn ich damit richtig liege, kanns doch nicht das Problem sein, eine gleiche Relation auch für Layout->LayoutPositionen zu konfigurieren, oder habich was in falschen Hals gekriegt?

    (Ich wundere mich aber über db.Vorlagen.Remove(v); - müsste das nicht iwie .Delete heissen?
    Bei Dataset kann man auch Removen, mit der Auswirkung, dass der Vorgang anne Änderungsverfolgung vorbei geht, und also nicht in die DB persistiert.)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()