Typisiertes Dataset mit n:m Relation in zwei DataGridView darstellen

  • VB.NET
  • .NET 4.5

SSL ist deaktiviert! Aktivieren Sie SSL für diese Sitzung, um eine sichere Verbindung herzustellen.

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

    Typisiertes Dataset mit n:m Relation in zwei DataGridView darstellen

    Hi,

    ich steh gerade mal da wie der Ochs vorm Berg. Und das Problem kann doch gar nicht so schwer sein.
    Ich hab da ein Dataset mit drei Tabellen und zwei 1:n Relationen, so sieht das aus:


    Auf meiner Form habe ich drei DGVs, die das abbilden:



    Zwei davon sind auch synchronisiert, also wenn ich links klicke, erscheinen in der Mitte die zugehörigen Datensätze:


    Das Dritte rechts ist aber autark, also was die Klickerei angeht. Ich würde das aber gern so haben, dass, wenn man links was klickt, dann die entsprechenden Datensätze rechts angezeigt werden. Mit einem Filter auf dem Click-Event im mittleren DGV geht das ziemlich einfach. Aber da ist die Bedingung auch "einfach". Aber mit Klick im linken DGV wäre der Filter für Rechts eine Liste von Id_Melder.

    -> Wie baut man die (Liste) aus der BindingSource auf und wie wendet man das dann als Filter an? ?(

    Aber jetzt hab ich ein spannenderes Anliegen. Ich möchte aus der dem DGV rechts zugrunde liegenden Tabelle zwei Spalten in dem DGV in der Mitte anzeigen, nämlich Nachname und Vorname.
    Mit berechneten Spalten im DGV bekommt man das wohl hin Melder.Expression= Parent(Melder_ICa).kMelder, aber geht es auch on thy fly im DGV?
    [Edit 170924]Ja klar, ganz einfach mit einer ComboColumn :rolleyes:


    Kleiner Exkurs: Beim Tippen dieser Worte kommt mir eine Frage in den Sinn. Warum eigentlich nicht mit ColumnExpressions arbeiten? Wie ist das denn eigentlich mit dem Speicherplatz? Habe ich dann die ganzen Namen der Melder doppelt und dreifach im Speicher oder wird das nur referenziert?

    Wieder zurück zum Problem. Ich möchte nicht einfach nur den Nachnamen im mittleren DGV, sondern den nur, wenn das Feld kNachname leer ist, sonst kNachname (siehe DataSet). Es sollte also eine Formel oder besser eine Funktion hinterlegt werden können. (Erklärung: Die Namen werden vom Benutzer im Feld kNachname korrigiert. Die Korrekturen werden beim erneuten Import beibehalten.)
    [Edit 170924]Auch hier habe ich nun einfach auf die ColumnExpressions zurückgegriffen. Typ + ': '+ iif(kNachname='',Nachname,kNachname) +', '+ iif(kVorname='',Vorname,kVorname) +' ('+ iif(kOrt='',Ort,kOrt)+')' Die Felder kNachname, kVorname dürfen nicht <DBNull> sein, der Standard-Nullwert ist String.Empty. Damit klappt der iff-Vergelcih. Sonst müsste man hier wohl mit verschachtelten ifnull() arbeiten.

    Yo, klappt soweit alles. Wäre trotzdem schön, wenn die Frage oben noch geklärt würde und mich jemand bzgl. des Speicherbedarfs von berechneten Spalten aufklären könnte :thumbsup:

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „OliverSte“ ()

    OliverSte schrieb:

    Wie ist das denn eigentlich mit dem Speicherplatz? Habe ich dann die ganzen Namen der Melder doppelt und dreifach im Speicher oder wird das nur referenziert?
    ich weiss es nicht wirklich, aber String ist eine Referenz-Klasse, da wird vmtl. nur eine Referenz im Speicher rumfahren.
    Ich hab' das mal getestet, indem ich einige ColumnExpressions auf eine andere Tabelle aufgbaut habe, um aus den Spalten NAME und VORNAME eine berechnete Spalte Suchbegriff:"NAME, VORNAME" zu erstellen.
    Das zugehörige Dataset wurde dann alls XML gespeichert, und siehe da:Bei Anschauen in einem Texteditor war der Feld-Eintrag SUCHBEGRIFF vorhanden, und alle berechneten Felder als Klartext, z.B. "Müller, Lieschen".
    Daher liegt der Scluss nahe, dass sich dies auch beim Füllen des Datasets im Speicher niederschlägt.
    Finde nicht, dass dies ein hinreichender Beweis ist. Was soller denn beim Export sonst schreiben, als das Ergebnis der Berechnung?

    Ne, da müsste man sich mal die Speichernutzung angucken, wenn man Zigtausende Datenzeilen hat. Will das mal wer testen?
    Tabelle mit Name, Vorname als XML speichern. Dann im DataSet zusätzlich zwei Spalten mit Expressions darauf einbauen, Vorname+Nachname und umgekehrt.
    Da hinein das XML laden.
    Nun müsste die Speicherbelegung verdreifacht sein.
    Wenn man eine Datenbank generiert, wie oben beschrieben. Dann einen Speichersnapshot erstellt nur mit Name, Vorname und einen weiteren mit berechneten Spalten, ist entweder eine Verdopplung (oder mehr) zu sehen, oder nur ein geringeres Plus.
    Hab mal ein typDS mit 4 Spalten erzeugt, wobei gilt:
    Spalte 1 => Byte
    Spalte 2, 3, 4 => String
    Wert von Spalte 4 = Wert von S2+S3
    bei 100000 Zeilen springt die Speicherbelegung von 6 MB auf 55 MB. Ist der Inhalt von S4 = Null, dann sind es 54 MB => ist das ausreichend Beweis, dass da wohl nur auf die anderen Spalten verwiesen wird? (Das ist ernst gemeint, nicht rhetorisch-polemisch)

    EDIT: Ich kann mir die Frage selbst beantworten, da ich den Gegentest vergaß: Wenn in S4 auch ein String drinsteht, ist die Speicherbelegung auch bei 55 MB :S

    EDIT2:
    100000x S2: Random-String mit 10 Zeichen, S3: Random-String mit 10 Zeichen, S4-Werte = Nothing => 60,5 MB
    100000x S2: Random-String mit 10 Zeichen, S3: Random-String mit 10 Zeichen, S4: Random-String mit 20 Zeichen => 76,5 MB
    100000x S2: Random-String mit 10 Zeichen, S3: Random-String mit 10 Zeichen, S4-Werte = S2+S3 => 68,4 MB
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von VaporiZed, mal wieder aus Grammatikgründen.

    ― Eine häufig von mir verwendete Abkürzung: CEs = control elements (Labels, Buttons, DGVs, ...)
    ― If Not GrammarIsOk() Then AssumeThatCodeIsOk = False
    ― »Oh, großes Spaghetticodemonster. Bitte schicke mir Durchblick! Oder zumindest eine Gabel. Oder – wenn es kein Besteck mehr gibt – zumindest Glasnudeln.«

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „VaporiZed“ ()

    Hey, das ist doch prima!
    Lt. Edit2 also eine Minus von 11% gegenüber String-Speicherung, ziemlich wenig. Allerdings, wie viele Bytes belegt so ein "Verweis" pro Variable, 4? Dann gingen für die Formel schon 9 drauf. Wahrscheinlich sind es mehr und der Effekt ist deshalb so gering. Probier mal mit Random-Strings von 50 Zeichen.

    Hast du die Solution jedesmal neu gestartet?

    Ich würde ja ein DataSet mit 2 Spalten machen, das random füllen und abspeichern. Wie ist die Speichernutzung (1)?
    Dann würde ich das Dataset um eine berechnete Spalte (a+b) erweitern und das zuvor gespeicherte DS hineinladen. Wie ist jetzt die Speichernutzung (2)? (hoffentlich wesentlich weniger als das doppelte).
    Dann das Ding abermals speichern, jetzt ist die berechnete Spalte mit in der XML. Die Formel löschen und das XML wieder laden. Wie ist jetzt die Speichernutzung (3)? (hoffentlich das doppelte von (1))
    Hmnaja, die weiteren Tests sind für mich jetzt zumindest ein wenig aufschlussreich. Ich erzeuge 2 alphanumerische Zufallsstrings mit je 50 Zeichen, ggf. noch einen weiteren mit 100 Zeichen.
    Zustand
    RAM-Verbrauch [MB]
    SSD-Verbrauch [MB]
    Leerlauf
    5,6
    0
    2x50er Strings+Leerstring
    69,5
    19,6
    reload aus XML ohne Formel
    70,3
    /
    reload aus XML mit Formel
    96,2
    /
    2x50er Strings+(Formel S1+S2)
    87,6
    29,6
    reload aus XML ohne Formel
    113,7
    /
    reload aus XML mit Formel
    98,6
    /
    2x50er+1x100er String
    84,9
    29,6
    reload aus XML ohne Formel
    113,7
    /
    reload aus XML mit Formel
    95,5
    /

    Die Formel im typDS spart im Vergleich zu einem "vollwertigen String" auf jeden Fall was ein. Zumindest im RAM. Auf der Platte hingegen gar nichts, da dort der Ergebniswert Formel als vollwertiger String persistiert, siehe Post#3.
    Zwischen jedem Test wurde die App neu gestartet, die Tests wurden ein paar mal zur Bestätigung der Ergebnisse wiederholt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von VaporiZed, mal wieder aus Grammatikgründen.

    ― Eine häufig von mir verwendete Abkürzung: CEs = control elements (Labels, Buttons, DGVs, ...)
    ― If Not GrammarIsOk() Then AssumeThatCodeIsOk = False
    ― »Oh, großes Spaghetticodemonster. Bitte schicke mir Durchblick! Oder zumindest eine Gabel. Oder – wenn es kein Besteck mehr gibt – zumindest Glasnudeln.«

    VaporiZed schrieb:

    Die Formel im typDS spart im Vergleich zu einem "vollwertigen String" auf jeden Fall was ein.
    Wow - dann bin ich schwer beeindruckt.
    Das bedeutet ja, dasser die berechneten Werte nicht zwischenlagert, um sie auf Abruf parat zu haben, sondern er berechnet auf Abruf jedesmal neu.
    Das muss dann eine vorkompilierte Function sein oder sowas, weil berechnete Spalten sind ja einigermassen schnell.