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.

    Bin noch unterwegs und nur am Handy...
    gucke gleich zu Hause nach.

    EDIT: OK, hab nun geschaut. Soweit ist es mir klar, mein Fehler was Seeding, da hab ich gedanklich zu kompliziert gedacht und deswegen so blöd verschaltet.
    Damit komme ich klar.
    Eins verstehe ich nur nicht, im Consolen Programm erstellst du einen neuen context und rufst dann die Seed methode auf, in dieser Seed Methode erstellst du wieder einen neuen context. Ist das so richtig? oder soll das Seed ins consolen Programm?

    Im Livebetrieb ist es ja so, das die DB durch mich erstmalig erstellt wird, dann erstelle ich die Person (eventuell später über eine Registrierung im Web), die das Programm benutzen will, diese Person (oder im besten Fall später mal sehr viele Personen) greifen über die AccessDaten immer auf Ihre eigenen Daten dazu, zu diesen Daten gehören dann je nach Rolle entweder alle Organisationsdaten inklusive Responsible, events, seller und artikel (ist dann der OrganisationAdmin) oder auf eingeschränkte daten, wie der EventAdmin, der darf nur seine eigens erstellte events und seine Seller verwalten, der Selller darf nur seine artikel verwalten. Die Zuordnung der Zugehörigkeit bildet die Organisation, deswegen die ICollection<Person> OrganisationPersons im Model. Sodass auch gewährleistet ist, wenn sich ein Seller oder ein Eventadmin oder OrganisationAdmin anmeldet, immer nur auf die daten seiner zugehörigen Organisation kommt.

    Alternative wäre ja, ich müsste für jeden Verein, der das Programm nutzen will eine eigene Datenbank anlegen, das könnten im besten fall dann hunderte sein...

    Oder denke ich schon wieder zu kompliziert?
    "Hier könnte Ihre Werbung stehen..."

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

    Eine Sache hab ich noch gefunden.
    Wenn die DB erstellt wird, und die Daten werden eingetragen, dann hat die erste Testperson die OrganizationId 1 und die beiden anderen Testporsen haben keine OrganizationId... sollten aber doch auch die Id 1 haben, denn es sind ja alle personen dieser Organisation.

    Ich glaub ich habs gefunden, im seed wird den OrganizationPersons nur die erste Person zugewiesen, hir müsste die Testperson Liste übergeben werden... teste ich aus

    Edit: wenn ich im seeding:

    C#-Quellcode

    1. newOrg.OrganizationPersons.Add(context.Persons.Local.ToList()[0]);
    2. newOrg.OrganizationPersons.Add(context.Persons.Local.ToList()[1]);
    3. newOrg.OrganizationPersons.Add(context.Persons.Local.ToList()[2]);

    schreibe, geht es und alle Personen bekommen die richtige ID der Organisation, zu der sie gehören.

    Edit2:
    in der Tabelle PersonBazaarEvent wird auch wieder eine OrganisationId angelegt. das kommt wohl von der Icollection OrganizationEvents aus dem Organization Model, das nehme ich raus, das wird da ja nicht benötigt, wenn ich alle events einer Organisation haben will, kann ich ja die BazaarEvent tabelle filtern, da wird die Id ja richtig eingetragen

    "Hier könnte Ihre Werbung stehen..."

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

    Hallo @Akanel

    Sorry, ich habe total vergessen auf deine Frage einzugehen.

    Akanel schrieb:

    Das damit eine "Zwischenspalte erstellt wird steht ja im Beitrag über mir. Aber was genau dort passiert verstehe ich nicht.
    Ich versuche mir das gerade wieder Bildlich vorzustellen wie die Tabellen dann im Datasetdesigner aussehen würden und was davon dann der ForeignKey ist.

    Eine Person (Verkäufer) soll mehreren Events zugeordnet sein können. Und ein Event soll aber mehrere Personen (Verkäufer) haben können.

    Das ist eine n:m Beziehung (Many-To-Many). Damit eine solche Beziehung Relationell abgebildet werden kann benötigt es eine Zwischentabelle.

    Warum? Bei einer 1:n Beziehung wie im Bild mit z.b. der ResponsiblePerson (Verantwortlicher) kann es für einen Event nur einen Verantwortlichen geben.
    Hier kann also in der Tabelle einfach die ID der Person welche Verantwortlich ist hinterlegt werden. Wenn die ID einer Person bei 12 Events hinterlegt ist, ist diese Person bei 12 Events als Verantwortlicher hinterlegt.
    Es kann also eine Person bei X Events als Verantwortlicher hinterlegt sein, aber ein Event kann nur einen Verantwortlichen haben. Das Klappt mitt der ID.



    Aber.... was bei einer n:m Beziehung. Wie oben schon gesagt soll ein Event X Verkäufer haben, aber ein Verkäufer soll bei X Events dabei sein können. Das kann nicht mit einer ID in den jeweiligen Tabellen abgebildet werden.
    Stell dir die Tabelle vor. Du brächtest ja eine Spalte wo mehrere IDs von Person (Verkäufer) drinnen sind. Das geht so nicht.

    Aus diesem Grund benötigt es eine Zwischentabelle (hier PersonBazaarEvent), welche nichts anderes macht als die IDs der Verkäufer mit der ID des Events verbindet.
    Ich habe in dem konkreten Beispiel mal einem Event 3 Verkäufer zugeordnet. Wie du siehst ist in der Zwischentabelle in der Spalte PersonID immer eine andere ID (die der zugeordneten Verkäufer) und in der Spalte BazaarEventId immer die gleiche ID (hier 1), nämlich die des Events.



    Schöne 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,
    da hat sich in der Erklärung ein kleiner Fehler eingeschlichen. Vom Inhalt her ist es richtig und entspricht genau dem Lastenheft, allerdings müsste man die Erklärung pauschalisieren, denn ein Event kann mehrere Personen haben und eine Person kann mehrere events haben. Das ist dann die n:m Beziehung. Wobei bei mir dann die Person, die meherere events haben kann der Responsible (verantwortliche) ist und die events die mehrere personen haben können dann die Verkäufer sind. Ist bisschen verwirrend weil beides Personen sind.
    "Hier könnte Ihre Werbung stehen..."
    Genau so habe ich es geschrieben:

    Nofear23m schrieb:

    Und ein Event soll aber mehrere Personen (Verkäufer) haben können

    Nofear23m schrieb:

    Wie oben schon gesagt soll ein Event X Verkäufer haben, aber ein Verkäufer soll bei X Events dabei sein können.
    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. ##

    Ähhh.... ich glaub ich steh aufm schlauch.
    ein Verkäufer gehört immer nur zu einem event, ein event kann mehrere verkäufer haben.
    ein Verantwortlicher kann für mehrere events verantwortlich sein, aber ein event hat immer nur einen Verantwortlichen.
    die Zwischentabelle brauchen wir ja deswegen, weil Verkäufer und Verantwortliche beides Personen sind.
    einmal die Person Responsible und einmal die Person Seller. Oder?
    eigentlich müssten bei deinem Beispiel oben ja in der PersonBazaarEvent 4 einträge sein, 3 verkäufer und 1 verantwortlicher.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    die Zwischentabelle brauchen wir ja deswegen, weil Verkäufer und Verantwortliche beides Personen sind.

    Leider Falsch. Die brauchst du bei JEDER Many-To-Many Beziehung. Unabhängig davon ob du nun weitere Beziehungen zu Person hast oder nicht.
    Einzig die Tatsache das X Personen einem Event zugeordnet sein können (als Verkäufer) und eine Person bei X Events als Verkäufer zugeordnet sein kann verlangt die Zwischentabelle.

    Das ist bei einer Datenbank IMMER so.

    Guck mal: en.wikipedia.org/wiki/Many-to-many_(data_model)

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

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

    Hi, ja, das hab ich ja verstanden. Nur du schreibst:
    „und eine Person bei X Events als Verkäufer“ da müsste es heißen: „und eine Person bei x Events als Verantwortlicher

    deswegen hatte ich das ja in meinem ersten Datenmodell aufgeteilt:
    1 Verantwortlicher = X Events,
    1 Event = 1 Verantwortlicher
    1 Event = x Verkäufer
    1 Verkäufer = 1 Event
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    und eine Person bei X Events als Verkäufer“ da müsste es heißen: „und eine Person bei x Events als Verantwortlicher

    Beides ist richtig. Eine Person kann bei X Events als Verkäufer und/oder als Verantwortlicher fungieren.
    Der Unterschied ist nur das es für ein Event nur EINEN Verantwortlichen geben kann aber X Verkäufer. ;)
    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. ##

    Ok, du zielst darauf ab, das ein Verantwortlicher auch gleichzeitig ein Verkäufer sein kann.
    in meiner denke müsste BazaarEvent eigentlich keine Collection von PersonEvent haben die Sellers heißt, sondern eher eine Collection von Person die Sellers heißt.
    "Hier könnte Ihre Werbung stehen..."
    @MichaHo
    Edit: Aber es benötigt die Zwischentabelle also kann es keine Collection Of Person sein weil n:m!
    Schau dir nochmal den Wiki Link 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. ##

    Ok, da ist meine denke dnn irgendwie noch konfus.
    ich setze mich morgen weiter daran und versuche mal den Datenabruf über die LogInDaten zu machen.
    erstmal nur in der console, damit ich nachher weis wie es geht. Muss mal schauen welche der 3 EF Methoden zum laden die beste dafür ist.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    Ok, da ist meine denke dnn irgendwie noch konfus.

    Warum, das eine ist eine 1:N beziehung und das andere eine N:M.

    Eine Person kann als Verkäufer bei X Events fungieren.
    Eine Person kann bei X Events als Verantwortlicher fungieren.

    Ein Event hat X Verkäufer zugeordnet.
    Ein Event hat einen Verantwortlichen.

    Und ja, ein Verantwortlicher kann im Grunde auch gleichzeitig ein Verkäufer sein. Ist das nicht erwünscht musst du das im Programm dann steuern. Aber von der Datenhaltung her ist es möglich.
    Beides sind Personen was auch gut so ist. Thema Normalisierung.

    MichaHo schrieb:

    Muss mal schauen welche der 3 EF Methoden zum laden die beste dafür ist.

    Wie meinst du das? Da kommt es auf sehr viele Faktoren an. Die wohl wichtigste und wo die meisste Performance herausgeholt werden kann ist das Thema Tracking vs NoTracking

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

    Ahhhh.... so, jetzt sind meine Denke wieder da... so wie du es oben geschrieben hast, ist korrekt und konform mit meiner Denke...puhh...

    ich meinte die 3 Methoden des Abrufens von Daten, also EagerLoading, Explicites Laden oder LazyLoading.
    "Hier könnte Ihre Werbung stehen..."
    Gerne können wir das dann genauer durchgehen, hierfür würde ich aber einen neuen Thread aufmachen.

    Aber kurz.... Das kommt auf die Situation an. LazyLoading ist Böse. Gott sei Dank kann EF Core das im Gegensatz zu EF 6 nicht mehr OutOfTheBox. Das ist auch gut so. LazyLoading ist der Performancekiller schlechthin.
    Was macht LazyLoading? Es läd benötigte Daten nach. Gaaanz schlecht. Im schlimmsten Fall hast du bei der Anzeige eines DataGrids mit 200 Datensätzen mind. 201 Datenbankroundtrips. Kannste dir denken wie toll das ist.

    EagerLoading ist das beste wenn du im Vorfeld beim abrufen der Daten genau weist welche verbundenen Daten (z.b. rufst du Personen ab und willst die Events mit abrufen wo diese Verkäufer ist) du benötigst. Somit sagst du EF mit Include das du das mitabrufen willst. EF schickt dann einen SQL mit Joins an die DB.

    ExplizitLoading ist am besten wenn du Entweder später Verknüpfte Daten nachladen möchtest oder du genau weist das du hier sehr viele Datensätze der Verknüpften Tabelle zurückbekommen wirst.
    Das ist auf der DB schneller wie ein JOIN. Jedoch.... das klappt nur wenn mit Tracking abgerufen wird da sonst das Relationship-Fixup von EF nicht funktioniert.

    Aber wie gesagt, genauer dann in einem neuen Thread.

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

    Ich mal wieder, habe ne Frage.
    Wenn ich das richtig gesehen habe wird im Model Annotation und FluentAPI genutzt.
    Jetzt mein Frage: Warum beides? Welchen Vorteil hat dies?

    Ich habe gelesen das FluentAPI den höchsten Vorrang hat, überschreibt also Annotation. Mann kann beides nutzen, muss es aber nicht, wenn ich das richtig verstanden habe.
    Mit FluentAPI kann man ja bei einer m:n beziehung die zwischentabelle erstellen. Geht das auch ohne? Rein mit Annotation? Ich habe dazu noch nichts gefunden.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.

    Akanel schrieb:

    wird im Model Annotation und FluentAPI genutzt.
    Jetzt mein Frage: Warum beides? Welchen Vorteil hat dies?

    Im Model gibt es keine FluentAPI, die gibts nur im Context. (Methode OnModelCreating)
    Wo wurde beides genutzt? Man sollte immer entweder oder verwenden. Ich mache das so das ich die Dinge die man per Annotation komfortabel und ohne einschränkung konfigurieren kann auch über Annotation konfiguriere.
    Alles andere dann über die FluentAPI.

    Akanel schrieb:

    Ich habe dazu noch nichts gefunden.

    Nein, n:m geht nur über die API

    Alles in den Docs von EF Core.
    z.b. n:m hier.

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

    Ok habe mich wohl falsch ausgedrückt.
    Klar im Model wird Annotation verwendet und Context dann Fluent.

    Danke für den Link. Soweit war ich im Lesen noch nicht.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    OK, wichtig ist nur das man nicht beides macht. Klar, dann würde die FluentAPI gewinnen.

    Also setzt du einen DefaultValue für eine Eigenschaft per Annotation und und dann einen anderen Wert per Fluent API gewinnt die Fluent API.
    Und du schaust dir die Annotation an und denkst dir. Whaaat? Warum hab ich denk komischen Wert da drinnen.

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