DatenModellierung Problem (Veranstaltung eines Vereins)

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 139 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    MichaHo schrieb:

    Wie sag ich dem Seller das er zu dem erstellten basar gehört?

    C#-Quellcode

    1. basar.Sellers.Add(new PersonEventModel() {Person = sellers.First(),Event = basar});


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

    Du musst hald gucken das eine neue List(Of) vorher erstellt wird.

    C#-Quellcode

    1. basar.Sellers = new List<PersonEventModel>();
    2. basar.Sellers.Add(new PersonEventModel() {Person = sellers.First(),Event = basar});


    Wobei hier noch zu sagen ist das du in diesem Fall dann vom Seller "Maria" nicht die Refernez auf den Event bekommt, denn müsstest du noch mit angeben, das macht dir aber sobald EF Core dranhängt EF Core selbsttätig wenn NavigationProperties mit Overridable deklariert sind, aber dazu kommen wir ja später.

    Derweil müsstest du das noch händisch machen:

    C#-Quellcode

    1. basar.Sellers = new List<PersonEventModel>();
    2. basar.Sellers.Add(new PersonEventModel() {Person = sellers.First(),Event = basar});
    3. sellers.First().PersonEvents = new List<PersonEventModel>();
    4. sellers.First().PersonEvents.Add(new PersonEventModel() { Event = basar, Person = sellers.First() });


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

    Ahhh, da war ich fast auf dem richtigen Weg....
    ich habs jetzt so eingebaut zum testen:

    C#-Quellcode

    1. static void Seed2()
    2. {
    3. PersonModel organizer = new PersonModel() {FirstName = "Förderverein", LastName = "KiTa Kunterbunt e.v.", IsOrganizer = true, License = LicenseTypeEnum.Free };
    4. PersonModel responsible = new PersonModel() { FirstName = "Harald", LastName = "Muster", Email = "harald@muster.com", IsSeller = false };
    5. EventModel basar = new EventModel();
    6. EventModel basar2 = new EventModel();
    7. List<PersonModel> sellers = new List<PersonModel>();
    8. List<ArticleModel> articles = new List<ArticleModel>();
    9. sellers.Add(new PersonModel(){ FirstName = "Maria", LastName = "Muster", SellerNumber = 1, PersonEvents = new List<PersonEventModel>() { new PersonEventModel() {Event = basar } } });
    10. sellers.Add(new PersonModel() { FirstName = "Helga", LastName = "WatWeisIch", SellerNumber = 2, PersonEvents = new List<PersonEventModel>() { new PersonEventModel() { Event = basar2 } } });
    11. sellers.Add(new PersonModel() { FirstName = "Irmtraut", LastName = "HasteNichtGesehen", SellerNumber = 3, PersonEvents = new List<PersonEventModel>() { new PersonEventModel() { Event = basar } } });
    12. articles.Add(new ArticleModel() { ArticleNumber = 123, Description = "Spiel - Schnappt Hubi", Price = 2.5m, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 1) });
    13. articles.Add(new ArticleModel() { ArticleNumber = 456, Description = "türkisblaue Jacke", Price = 5, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 2) });
    14. articles.Add(new ArticleModel() { ArticleNumber = 789, Description = "bunte Hose", Price = 0.5m, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 3)});
    15. articles.Add(new ArticleModel() { ArticleNumber = 1011, Description = "Häßliche Mütze", Price = 25, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 1) });
    16. articles.Add(new ArticleModel() { ArticleNumber = 1012, Description = "Jacke", Price = 2, Quantity = 1, Size = "140/146", Person = sellers.Find(s => s.SellerNumber == 2) });
    17. articles.Add(new ArticleModel() { ArticleNumber = 1013, Description = "Hose", Price = 4, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 1) });
    18. articles.Add(new ArticleModel() { ArticleNumber = 1014, Description = "Turnhose", Price = 1, Quantity = 2, Person = sellers.Find(s => s.SellerNumber == 3) });
    19. articles.Add(new ArticleModel() { ArticleNumber = 1015, Description = "Kaufladen mit Zubehör", Price = 25, Quantity = 1, Person = sellers.Find(s => s.SellerNumber == 1) });
    20. basar.Organizer = organizer;
    21. basar.ResponsiblePerson = responsible;
    22. basar.EventName = "Kleiderbasar Musterhausen";
    23. basar.EventDate = DateTime.Now.AddDays(14);
    24. basar2.Organizer = organizer;
    25. basar2.ResponsiblePerson = responsible;
    26. basar2.EventName = "Grillfeier KiTahausen";
    27. basar2.EventDate = DateTime.Now.AddDays(14);
    28. foreach (var art in articles)
    29. {
    30. foreach (var ev in art.Person.PersonEvents)
    31. {
    32. System.Console.WriteLine($"Artikel: {art.ArticleNumber} - {art.Description} - Größe: {art.Size} - Preis: {art.Price} - Verkäufer/Nr.: {art.Person.FullName}/{art.Person.SellerNumber} - Veranstaltung:{ev.Event.EventName}");
    33. }
    34. }
    35. }
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    ich habs jetzt so eingebaut zum testen

    Viele Wege führen nach Rom.

    Jetzt ist dann wichtig das du definiert wie große welche Felder sein dürfen. Plichtfelder definieren und Default-Werte.

    Dann eine Klassenbibliothek mit EF Core um den rest zu konfigurieren.

    Langsam ist es dann auch soweit das du dich entscheiden solltest üb .Net Core und nicht. Also im Grunde ob es ein Linux Server werden wird auf dem EF Core laufen wird oder ein Windows Server. Wobei ich das Model und EF Core auf jeden Fall in .Net Code bzw. .Net Standard erstellen würde.

    Obwohl Corrs-Plattform fähig würde ich trotzdem einen Windows Server verwenden, einfach um auf der sicheren Seite zu sein, da das alles noch sehr neu ist traue ich dem ganzen irgendwie noch nicht, probiert habe ich es auch noch nicht.

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

    Hi,
    ich hätte Zugriff auf einen Windows Server, muss nur noch den Preis verhandeln :)

    Eine Frage noch zum iDataErrorInfo... soll ich das nur in den Klassen implementieren, wo es benötigt wird, oder in der ModelBase?
    Ich erstelle mal die Projektmappe neu und stelle das Modelprojekt auf .Net Standard, mal schauen was mich dann erwartet :)
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    ich hätte Zugriff auf einen Windows Server, muss nur noch den Preis verhandeln

    Das wäre Ideal.

    MichaHo schrieb:

    Eine Frage noch zum iDataErrorInfo... soll ich das nur in den Klassen implementieren, wo es benötigt wird, oder in der ModelBase?

    Naja, da du ja (nehme ich an) jedes Model Validieren können willst eher in Modelbase.

    Guck dir mal mein Model in der WPFNotes2 App an. Dort habe ich das (wie ich finde) recht sauber implementiert.

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

    da war ich gerade dabei dahinter zu steigen mit ModelValidation und ModelValidator.... übersetze es jetzt erstmal nach C#

    Muss ich die System.ComponentModel.DataAnnotations über nuget rein holen?
    Im .Net Standard gibt es ja die Verweise nicht mher
    "Hier könnte Ihre Werbung stehen..."
    Jep, musst du über NuGet holen.

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

    Sorry das ich mich hier einmische, aber zu folgendem hätte ich mal eine Frage.

    Nofear23m schrieb:

    EF Core, Serialisierung?

    Weil die Models würden für beides anders aussehen!


    Könntest du mir mal ein kleines Beispiel geben was genau sich da unterscheidet?
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Hallo @Akanel

    Kein Problem, mach ich gerne.

    Du musst immer daran denken wie gespeichert wird. Arbeite ich mit einem OR Mapper wie EntityFramework bilde ich ja quasi ein Relationelles Datenmodell in Klassen ab (CodeFirst).
    Das O/R Mapper wie EntityFRamework so einiges am Kasten haben muss ich hier nicht so kompliziert denken. Ich kann das Modell so abbilden wie es tatsächlich in der "echten Welt" auch ist.

    Nehmen wir mal ein Beispiel mit Personen welche an einer Konferenz teilnehmen können.


    Hier ist das Model so abgebilted wie es tasächlich auf ist. Eine Person hat eine Adresse, an einer Konferenz können n Personen teilnehmen. Und auch die Konferenz findet an einer Adresse statt.

    Somit kann ich in der Conference.vb einfach ein Property Address As Destination haben.

    Warum?
    Bilde ich das ganz in einer Datenbank ab (was EF ja macht) bekommt jede Klasse (in der Regel) eine Tabelle. In der Tabelle Destinations sind alle gespeicherten Adressen vorhanden. Die Adressen werden dann über Fremdschlüsselspalten über die PersonId oder die ConferenceId miteinander verknüpft. Ist in der spalte ConferenceId der Destination Tabelle eine ID einer Conference habe ich damit eine verknüpfung der Adresse mit einer Konferenz.
    Ändere ich nun den Konferneznamen und speichere das ganze wieder bleibt die Adresse wie sie ist. Lade ich nun die Konferenz mit der Adresse wo sie stattfindet und ändere die Adresse wird der Datensatz in der Tabelle Addresses welche die AddressId hat geändert und durch die Verknüpfung über die Fremdschlüsselspalte funktioniert das auch. OK, ich hoffe ich konnte das halbwegs vermitteln. Weiter....

    Speichern über Serialisierung
    Hier kommt es nun wieder darauf an WIE ich speichere. Im normalfall würde ich wohl eine XML mit verfügbaren Adressen speichern, eine mit allen Konferenzen und eine mit Personen.
    OK, nun habe ich drei Dateien. Sehen wir uns das mal an wenn das Model so bleiben würde.

    Ich gebe ein paar Adressen ein und speichere diese in der Datei "Adressen.xml". Nun gebe ich zwei Konfernezen inkl. 5 Teilnehmern und einer Adresse ein und speichere diese unter "Konferenzen.xml".
    Die XML "Konferenzen.xml" wird nun so aussehen das hier alle Konferenzen drinnen sind, aber inkl. Adresse und den Teilnehmern. Weil einfach die Klasse Serialisiert wird (mit allen darin enthaltenen Properties).
    OK, nun ändere ich eine Adresse in der "Adressen.xml" und speichere. Ups, die Adresse hat sich nun bei der Konferenz NICHT geändert. Ja, weil es keinerlei verweise gibt.
    Die Adresse steht in beiden Dateien drinnen, ändere ich diese an einer stelle wird die änderung ja nicht auf die zweite Datei übertragen. Wie auch.

    Das ist der Grund für das zweite Modell:

    Hier gibt es nun kein Property Address in der Conference.vb mehr. sondern nur noch die ID.
    Man muss nun nach dem laden der Konferenzen alle Adressen laden und die Adresse mit der ID raussuchen um diese dann z.b. im ViewModel zu verbinden.
    Nur so bleiben im Falle der Serialisierung konsistent.

    OK, nun kann man sagen: Na dann speichere ich ALLE in EINER Datei (nur Konferenzen.xml), auch das wird früher oder später schiefgehen, da die korrekte persistierung der Daten nicht gewährt ist.
    Was ist wenn ich eine Adresse eingeben möchte, diese aber weder einer Person noch einer Konferenz zugeordnet ist, würde nicht klappen.

    Und warum nun GUID statt Integer für die Primärschlüssel?
    In einer Relationelle Datenbank kann die DB den Schlüssel selbst erzeugen und kann selbst den neuen noch nicht verwendeten Wert finden. Hier reicht uns Integer.
    Bei der Serialisierung klappt das nicht, hier müssten wir das manuell machen was mit Integer eher mühsam wäre, man müsste immer sehen was der höchste Wert war und dann hochzählen, also nehme ich da immer Guid.

    Ich hoffe das konnte man einigermaßen verstehen.

    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
    Vielen Dank für deine sehr ausführliche Beschreibung.
    Damit haben sich bei mir gerade ein paar Verständnisprobleme gelöst.
    Da ich diesen Beitrag aber nicht kapern möchte Schreibe ich weiteres in einem anderen oder Extra Thread.
    Vielen Dank.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Das freut mich.

    Ja, gerne. Mach einen neuen Thread auf.

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

    Halt!

    EF kann auch Guid!
    Normalerweise wenn ich mit einer DB arbeite nehme ich Integer aber EF kann genauso eine GUID als Primärschlüssel verwenden.
    Mir gefällt es nur nicht wenn ich die Tabellen aufmachen um nachzusehen ob richtig gespiechert wurde und muss dann so lange GUIDs vergleichen. <X

    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:

    Guck dir mal mein Model in der WPFNotes2 App an. Dort habe ich das (wie ich finde) recht sauber implementiert.

    Bin ich blind oder finde ich in den Models keine Implementation von IDataErrorInfo?
    Mit den DataAnnotations wie ich die setze weis ich, aber ich muss doch in der Modelbase die Errors usw. sammeln, oder nicht?

    EDIT: noch ne andere Frage, müssen alle Properties in den Models alle überschreibbar sein? wenn ja, warum?
    "Hier könnte Ihre Werbung stehen..."

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

    Hallo Michael

    MichaHo schrieb:

    Bin ich blind oder finde ich in den Models keine Implementation von IDataErrorInfo?

    Ne, biste nicht. Wird nicht benötigt. benötigst du nur wenn nötig im ViewModel. IDataErrorInfo brauchst du nur dort wo eine bindung vorhanden ist. Warum das so ist, da müsste ich ausholen, das können wir gerne machen wenn du dort angekommen bist.

    MichaHo schrieb:

    Mit den DataAnnotations wie ich die setze weis ich, aber ich muss doch in der Modelbase die Errors usw. sammeln, oder nicht?

    Meine Methoden richten sich nach den DataAnnotations. Geht alles OutOfTheBox (später im ViewModel ist dann die abfrage).

    MichaHo schrieb:

    noch ne andere Frage, müssen alle Properties in den Models alle überschreibbar sein?

    Im Grunde nur die NavigationProperties.(braucht EF Core in gewissen Situationen - kann ich auch gerne genauer erklären) Es schadet aber nicht wenn du es überall drinnen hast.

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

    Hi Sascha,
    OK hab ich verstanden, Danke Dir.
    ich hab nun die Models soweit angepasst, aus guid hab ich int gemacht.
    ich hab deine Protocol und Setting noch übernommen, bin aber noch nicht ganz dahinter gestiegen.
    das frag ich dann aber in dem WPFNotes2 Thread.
    kann heute leider nicht dran weiter arbeiten, würde aber später mal die jetzige Version hoch laden.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    das frag ich dann aber in dem WPFNotes2

    Jo, mach das ruig.

    MichaHo schrieb:

    würde aber später mal die jetzige Version hoch laden

    Gut, ich schau dann mal schnell drüber!
    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. ##