Beispieldaten für eine viele zu viele Beziehung laden.

  • C#

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von hlghyr.

    Beispieldaten für eine viele zu viele Beziehung laden.

    Hi Forum!
    Nicht selten steht man vor der Aufgabe einige Beispieldaten in die Datenbank zu laden (seed). Bei einer "null oder 1 zu viele" oder "1 zu viele", ist das kein Problem. Doch wie sieht es bei einer "viele zu viele" Beziehung aus. Entweder man entwirft sein Model so, das man auf "viele zu viele" Beziehungen mit Hilfe einer Jointabelle verzichtet oder man macht folgendes.
    Model:
    Spoiler anzeigen

    C#-Quellcode

    1. public class Adresse
    2. {
    3. public Adresse()
    4. {
    5. Kunden = new HashSet<Kunde>();
    6. }
    7. public int Id { get; set; }
    8. public string Strasse_Nr { get; set; }
    9. public string Postleitzahl { get; set; }
    10. public string Ort { get; set; }
    11. public virtual ICollection<Kunde> Kunden { get; set; }
    12. }
    13. public partial class Kunde
    14. {
    15. public Kunde()
    16. {
    17. Adressen = new HashSet<Adresse>();
    18. }
    19. public int Id { get; set; }
    20. public string Name { get; set; }
    21. public string Vorname { get; set; }
    22. public string Anrede { get; set; }
    23. public int? FirmaId { get; set; }
    24. public virtual ICollection<Adresse> Adressen { get; set; }
    25. }


    Das Entity Framwork legt eine Jointabelle an aber diese können wir nur über die Navigationseigenschaften ansprechen. Ansonsten ist diese versteckt.

    Seedmethode
    Spoiler anzeigen

    C#-Quellcode

    1. protected override void Seed(DeinContext context)
    2. {
    3. var borhel = new Kunde { Id = 10, Name = "Borad", Vorname = "Helmar", Anrede = "Herr", FirmaId = 1 };
    4. var bortru = new Kunde { Id = 11, Name = "Borad", Vorname = "Trude", Anrede = "Frau", FirmaId = 2 };
    5. var patmax = new Kunde { Id = 12, Name = "Pattok", Vorname = "Max", Anrede = "Herr", FirmaId = 2 };
    6. var gen34 = new Adresse { Id = 8, Strasse_Nr = "Gensingerstraße 34", Postleitzahl = "10896", Ort = "Berlin" };
    7. var bol69 = new Adresse { Id = 9, Strasse_Nr = "Bolzstraße 69", Postleitzahl = "10897", Ort = "Berlin" };
    8. var par78 = new Adresse { Id = 10, Strasse_Nr = "Parkstraße 78", Postleitzahl = "10895", Ort = "Berlin" };
    9. borhel.Adressen.Add(gen34);
    10. bortru.Adressen.Add(gen34);
    11. bortru.Adressen.Add(bol69);
    12. patmax.Adressen.Add(par78);
    13. patmax.Adressen.Add(bol69);
    14. context.Kunden.Add(borhel);
    15. context.Kunden.Add(bortru);
    16. context.Kunden.Add(patmax);
    17. context.SaveChanges();
    18. }


    Man braucht sich nicht um die Id's in der Jointabelle kümmern. Das macht das Entity Framework.
    Ich hoffe, das kann mal jemand gebrauchen. Wenn jemand einen besseren Weg kennt, wäre ich sehr daran interessiert.

    Gruß Helge
    Achtung: Gilt nur für das Entity Framework 6. (Der Ordnung halber)
    Bis Dato (EF Core 2.0) kann EntityFramework Core keine N:M Beziehungen ohne Zwischenentität abbilden.

    Workaround:
    Eine Zwischentabelle mit Rückverweis inkl. Key und in OnModelCreating z.b. für die Beziehung Mandant Geschäftspartner:

    C#-Quellcode

    1. modelBuilder.Entity<ClientBusinessPartner>().HasKey(c => new{c.BusinessPartnerId,c.ClientId});
    2. modelBuilder.Entity<ClientBusinessPartner>().HasOne(c => c.Client).WithMany(b => b.BusinessPartners).HasForeignKey(c => c.ClientId);
    3. modelBuilder.Entity<ClientBusinessPartner>().HasOne(c => c.BusinessPartner).WithMany(b => b.Clients).HasForeignKey(c => c.BusinessPartnerId);


    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. ##

    @Sio_x dazu kennen wir doch nicht den Kontext?
    Du hast in einer MVVM Architektur das Model getrennt vom Rest. Da MUSS jede Entitäteneigenschaft Public sein. Warum denn auch nicht?
    Willst du von z.b. einem VM aus nicht auf deine PRoperties = Spalten in einer DB Tabelle zugreifen??

    Wäre doof oder?

    Mal ganz abgesehen das hier keine Anfragen zu sehen sind. Das ist OnModelCreating!!! Bitte lese nochmals. Danke

    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. ##

    Entweder er hat es sich weder nicht durchgelesen oder er weis nicht was es mit dem EF auf sich hat. Vorallem, auch der Setter muss Public sein, sonst könnte ich ja lesen aber nie in die DB schrieiben.

    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:

    Entweder er hat es sich weder nicht durchgelesen oder er weis nicht was es mit dem EF auf sich hat. Vorallem, auch der Setter muss Public sein, sonst könnte ich ja lesen aber nie in die DB schrieiben.

    Grüße
    Sascha


    Da bin ich komplett bei dir. Aber wenn du im Setter nie eine Prüfung der übergebenen Daten vorsiehst...?

    Sio_x schrieb:

    Aber wenn du im Setter nie eine Prüfung der übergebenen Daten vorsiehst...?

    ​Kann das sein das du noch nicht mit dem EF gearbeitet hast? Ich schreibe die Properties nicht mal aus. Prüfung sollte nie im Model passieren. Aber lassen wir das bitte, gehört nicht hier hin.
    ​Er wollte seine Erfahrung hier nur Teilen um anderen welche über Google hier her gelangen zu Helfen. Und das ist gut. Also bitte.
    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. ##

    Hi Forum!
    Mußte leider feststellen, das die Methode im 1. Post nicht gut ist. Beim debuggen werden jedes mal die gleichen Datensätze hinzugefügt. Dabei ist EF so freundlich und vergibt einfach andere Id's. Habe jetzt die Methode umgeschrieben, so das dies nicht mehr passieren kann.
    Spoiler anzeigen

    C#-Quellcode

    1. protected override void Seed(DeinContext context)
    2. {
    3. var kundenAddr = new List<Kunde>
    4. {
    5. new Kunde { Id = 10, Name = "Borad", Vorname = "Helmar", Anrede = "Herr", FirmaId = 1,
    6. Adressen = new List<Adresse>() },
    7. new Kunde { Id = 11, Name = "Borad", Vorname = "Trude", Anrede = "Frau", FirmaId = 2,
    8. Adressen = new List<Adresse>() },
    9. new Kunde { Id = 12, Name = "Pattok", Vorname = "Max", Anrede = "Herr", FirmaId = 2,
    10. Adressen = new List<Adresse>() }
    11. };
    12. foreach (var kunde in kundenAddr)
    13. context.Kunden.AddOrUpdate(kunde);
    14. context.SaveChanges();
    15. var adressenKun = new List<Adresse>
    16. {
    17. new Adresse { Id = 8, Strasse_Nr = "Gensingerstraße 34", Postleitzahl = "10896", Ort = "Berlin" },
    18. new Adresse { Id = 9, Strasse_Nr = "Bolzstraße 69", Postleitzahl = "10897", Ort = "Berlin" },
    19. new Adresse { Id = 10, Strasse_Nr = "Parkstraße 78", Postleitzahl = "10895", Ort = "Berlin" }
    20. };
    21. foreach(var adresse in adressenKun)
    22. context.Adressen.AddOrUpdate(adresse);
    23. context.SaveChanges();
    24. AddOrUpdateKundeAdresse(context, 10, 8);
    25. AddOrUpdateKundeAdresse(context, 11, 8);
    26. AddOrUpdateKundeAdresse(context, 11, 9);
    27. AddOrUpdateKundeAdresse(context, 12, 10);
    28. AddOrUpdateKundeAdresse(context, 12, 9);
    29. context.SaveChanges();
    30. }
    31. private void AddOrUpdateKundeAdresse(DeinContext context, int kunde, int adresse)
    32. {
    33. var kun = context.Kunden.Find(kunde);
    34. var adr = kun.Adressen.SingleOrDefault(a => a.Id == adresse);
    35. if (adr == null)
    36. kun.Adressen.Add(context.Adressen.Find(adresse));
    37. }


    Gruß Helge