DataRows merken sich, ob sie noch da sind?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.

    DataRows merken sich, ob sie noch da sind?

    Hallo,

    bei folgendem Versuch eine Tabelle zu sortieren, macht das Programm schon wieder Auge. Ich versuche DataRows wegzuspeichern, bevor ich sie lösche, aber die Rows merken auch danach noch, dass ich sie lösche und dann rumst es, weil die mir nicht mehr ihre Spaltenwerte geben können.

    VB.NET-Quellcode

    1. Private Sub btnReSort_Click(sender As Object, e As EventArgs) Handles btnReSort.Click
    2. DtImportBindingSource.RaiseListChangedEvents = False
    3. Dim geordnet = (From t In DS1.DtImport Order By t.Datum).ToList
    4. DS1.DtImport.Clear()
    5. For Each element In geordnet 'Tja ja genau diese elements existieren nicht mehr, warum nicht?
    6. DS1.DtImport.AddDtImportRow(element.Datum, element.Minuten, element.Stunden)
    7. Next
    8. DS1.AcceptChanges()
    9. DS1.WriteXml("DS1.xml")
    10. DtImportBindingSource.RaiseListChangedEvents = True
    11. DtImportBindingSource.ResetBindings(False)
    12. End Sub

    Zu dem Kommentar: Also ja wegen .Clear, aber wieso sind die Datarows in der Liste nicht unabhängig von der Tabelle?

    PS: Sry, wahrscheinlich gehört das wieder zu Datenbankprogrammierung. Ich hab das Problem wieder eher in dem Allgemeinen Handling von Klassen und Objekten gesehen, auf dass es ankommt beim Programmieren. Ich bin sicher es gibt Äquivalenzen auch außerhalb von DataSet-Objekten.

    Viele Grüße

    Thema verschoben; Sobald es um DB oder DataSet geht, gehört es ins Unterforum Daten(bank)programmierung. ~VaporiZed

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

    Haudruferzappeltnoch schrieb:

    aber wieso sind die Datarows in der Liste nicht unabhängig von der Tabelle?

    Weil das eben genau diese Rows sind, die du in die Liste packst - und die haust du mit .Clear raus.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Mein Vorschlag: Sortierte Zeilen hinzufügen, danach die alten löschen:

    VB.NET-Quellcode

    1. DtImportBindingSource.RaiseListChangedEvents = False
    2. Dim geordnet = (From t In DS1.DtImport Order By t.Datum).ToList
    3. For Each element In geordnet
    4. DS1.DtImport.AddDtImportRow(element.Datum, element.Minuten, element.Stunden)
    5. Next
    6. For i = 0 To geordnet.Count - 1
    7. DS1.DtImport.RemoveDtImportRow(DS1.DtImport(0))
    8. Next
    9. DS1.AcceptChanges()
    10. DS1.WriteXml("DS1.xml")
    11. DtImportBindingSource.RaiseListChangedEvents = True
    12. DtImportBindingSource.ResetBindings(False)

    Stellt sich nur die Frage: Wozu? Datensortierung sollte im GUI stattfinden. Welchen Vorteil bringt Dir die Rohdatensortierung?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Wenn ich die DataTable nicht sortiere, dann muss ich die immer wieder im GUI sortieren. Beim nächsten laden sind die wieder unsortiert.

    RowState ist in der Liste nach dem Clear auch Detached
    Also die Datenzeilen sind noch da, haben aber ihre Werte verloren, weil sie keiner Tabelle mehr zugeordnet sind?
    Ich dachte mit Clear oder Remove mache ich Add rückgängig. Aber so hört sich das an als ob das Objekt das Add erzeugt weiter irgendwo rumgeistert.
    Ok in meiner Liste wäre das ja gewollt gewesen. Aber wie ist es allgemein?

    Ich habs jetzt so gemach wie du @VaporiZed. Aber sind die Removed Zeilen trotzdem noch irgendwie vorhanden, wenn ja wie entfernt man diese?

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

    Solange Du keine Abhängigkeiten in anderen Tabellen hast, ist das Sortieren vermutlich ok. Sobald aber eine andere Tabelle auf diese zu sortierende verweist, gibt's Probleme.
    mittelgroßer Spekulatius: Die Detached-Rows werden irgendwann vom GC entsorgt, sobald kein Verweis mehr auf sie existieren. Du kannst sie eh nicht mehr verwenden, von daher: einfach nicht mehr in ner Variable speichern und vergessen. Sie sind eh nutzlos.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Jede Tabelle hat ja (hoffentlich) eine ID-Spalte (Int32, Unique, AutoIncrement).
    Nun kann eine andere Tabelle eine Int32-Spalte haben, in der dann die ID einer Tabelle1-Zeile drinsteht. Diese Spalte wird normalerweise als ForeignID bezeichnet (Fremdschlüssel). Im tDS-Designer kann man dann die Tabellen durch Ziehen von der Tabelle2-ForeignID-Spalte auf die Tabelle1-ID-Spalte zeiehen und die beiden werden verknüpft. Das ist aber in den vier-Views-Videos vom EdR immer wieder Thema. Schau also da nochmal rein.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Haudruferzappeltnoch schrieb:

    Wenn ich die DataTable nicht sortiere, dann muss ich die immer wieder im GUI sortieren. Beim nächsten laden sind die wieder unsortiert.
    Ja, stimmt in gewisser Weise, ist aber auch genau so sinnvoll.

    Normalerweise baust du dein Programm stark nach MVVM (wenn es WPF ist) oder zumindest nach MVC-Pattern. Also du hast eine starke, strikt getrennte Verteilung vorgenommen. Bleiben wir bei MVC, so sind das Modell, View und Controller - also die Logik dahinter (im Übrigen ist MVC und MVVM sehr stark verzahnt und überaus ähnlich. Ich möchte fast sagen, man könnte das sogar gleichsetzen, auch wenn andere hier sofort aufschreien würden).

    Du hast also deine Modelle inkl. Daten. Das sind hierbei deine Listen. Diese liegen in einem unsortierten Zustand vor.
    Dein Controller verwaltet diese Daten in jedweder Form - also neue hinzufügen, alte löschen, vorhandene ändern und jeglicher anderer Piew Pa Pow.
    Dein View, also dein GUI, ist nun verantwortlich, diese Daten darzustellen. Und wenn du gleich von vorn herein dafür sorgst, dass dein GUI die Daten, die es vom Controller gespeist bekommt, in sortierter Form darstellt, brauchst du dich nicht zu kümmern, in welcher wirklichen Folge die Daten als Daten vorliegen und im Controller vorhanden sind. Denn dein GUI sorgt einfach selbst dafür, dass es die Daten, die es bekommt, so aufbereitet, dass sie für das GUI selbst sinnvoll angezeigt und behandelt werden können.

    Ist es nicht Haarspalterei, ob man es im GUI oder im Controller macht? Ja ! Aber Nein!

    Zugegeben, es spielt keine (wirkliche) Rolle, ob man die Daten im Modell, im Controller oder erst in GUI sortiert, filtert oder anderweitig filitieren möchte. Denn sind Daten im Modell, oder im Controller sortiert, muss dort die Sortierung stattfinden, dann braucht das GUI nur noch alles zusammenkratzen und darstellen. Andersrum, ist das GUI verantwortlich dafür, muss das nicht mehr in der Liste passieren. Insofern, da gebe ich Recht, spielt es keine Rolle, an welcher Stelle man das macht. Punkt, aus die Maus.

    Aber: Angenommen du hast Daten, die du nicht nur an einer Stelle anzeigen möchtest, sondern noch in einer zweiten GUI. Vielleicht sind diese Daten auch durch andere Dinge vermischt und der Controller handled das Vermischen dieser Daten - oder eben deren Zugehörigkeiten. Dann spielt es eine entscheidende Rolle. Wenn du nun im Modell oder im Controller die Listen sortierst, dann werden die geteilten Daten für alle GUI sortiert und gefiltert, denn dann ist es ja fix im Modell oder im Controller hinterlegt. Das gilt dann für alle gleich. Hast du nun eine zB alphabetische Reihenfolge angelegt im Modell, aber in der einen GUI kann man nach zB einer Kategorie filtern, hast du nun ein Problem, das auf andere GUI so zu übertragen, dass alles reibungslos funktioniert. Denn sobald du nun anfängst im Controller oder im Modell Daten zu verändern oder zu manipulieren, gilt das für alle GUI, die darauf zugreifen. Im schlimmsten Fall kann eine GUI damit nichts mehr anfangen oder du musst an entsprechender Stelle solche Dinge eben auffangen - was auch wieder unschön und nur unnötiger Mehraufwand darstellt.

    Deshalb gilt bei diesen Programmier-Pattern die strikte Trennung. Arbeitest du nach einem solchen Muster, sorgst du im Grunde dafür, dass dein GUI nicht die Daten im Controller verändert oder manipuliert, sondern es nutzt die Rohdaten und sorgt mit internen Regeln für eine grafische, aber lokale Anpassung. Bestes Beispiel hierfür ist: Du hast vier GUI, die alle deine Daten anzeigen. Eine Sicht hierfür ist die Admin-Sicht -> die zeigt alles an. die nächste Sicht ist für deine Mitarbeiter. Eine letzte für zB Kunden (Ja, so macht man das nicht - ich weiß, aber zum Veranschaulichen finde ich das Beispiel gut gewählt). Du fütterst alle Ansichten nun mit exakt den gleichen, nicht aufbereiteten Daten. Bei der Admin-Ansicht zeigt die Ansicht auch alle Daten entsprechend an. Die Ansicht der Mitarbeiter bekommt dieselben Daten, geht sie auch alle durch, blendet aber Dinge wie Administrationsdaten oder dergleichen aus -> bringt sie also gar nicht zur Anzeige, obwohl sie in den Daten vorhanden wären. Die Anzeige für Kunden hingegen zeigt zum Beispiel nur den Namen, vielleicht noch einen Preis an, aber hier werden alle Daten ausgeblendet, die den Kunden nichts angehen -> ZB Einkaufspreis, Stückzahl,... etc.

    Wenn du nach diesem Prinzip arbeitest, hast du den Vorteil, dass du deine Daten nicht anfassen musst, sondern lediglich bestimmen musst, wie du die Darstellung organisierst. Deine Daten bleiben also zu jeder Zeit für alle Ansichten und damit auch für alle Nutzer im Kern gleich. Wenn sich etwas ändert an deinem Modell, dann bekommen bei Aktualisierung alle diese Aktualität mitgeteilt und es wird bei allen wieder entsprechend der Vorgaben dargestellt.

    Und das ist - meiner Meinung nach - ein sehr großer Vorteil und ein guter Grund, warum man Daten strikt von deren Darstellung oder Verarbeitung trennen sollte. Denn nichts ist unschöner, als wenn man permanent Daten kopiert, vervielfältigt und irgendwann in den Zustand einer kaputten Datenintegrität rutscht und dann nicht mehr weiß, was eigtl wirklich ist.

    Dass bei diesem Beispiel - vor allem, wenn sie über unsichere Wege wie das Internet übermittelt werden - ein klarer Fehler darin liegt, alle Daten generell zu übermitteln, ist mir bewusst. Aber die Veranschaulichung finde ich dennoch gut, um zu verstehen, warum eine solche Abarbeitung sinnvoll sein kann.
    Danke @PadreSperanza für deine Ausführung.

    Eine Sache geht dabei jedoch voraus, die bei mir nicht gegeben ist. Und zwar dass man tatsächlich alle Daten schon hat.
    Ich habe sie nicht.
    Eine Tabelle die Messzeitpunkte loggt braucht zum Beispiel noch einen Deltawert, also die Dauer bis zum nächsten Zeitpunkt. Das kann der Datensatz aber zum Zeitpunkt seiner Erstellung noch gar nicht wissen. Man könnte auch die vergangene Zeit seit dem letzten Eintrag mitloggen. Aber auch das muss gebaut werden sozusagen. Und dann braucht es ja auch Platz in der Datenbank, aber eigentlich ist so eine Angabe redundant und braucht daher nicht permanent zusätzlich gespeichert sein. Daher hab ich es lieber nur in der Auswertung vorliegen.
    Ich gewinne also aus einer Rohtabelle eine kurzfristige Auswertungstabelle, dafür laufe ich z.B. mit einer Schleife durch die Rohdaten. Für einige Schleifen ist die richtige Sortierung sehr wichtig. Wenn ich nun die Rohdaten verändere manuell hinzufüge, wie in dem Fall, der diese Fragestellung aufgeworfen hat, dann muss ich einmal nach sortieren.

    Das passiert im SQL-Server z.B. von ganz allein, das heißt wenn man einen entsprechenden Index reinsetzt. Ich arme also nur dieses Indizierungs-Verhalten nach, weil ich hier keine echte Datenquelle nutze.
    Man kann solch Generation von Zusatzdaten auch mit dem richtigen Select anstrengen, habe ich auch schonmal probiert, das finde ich ist aber die Pest auf zwei Beinen.

    Haudruferzappeltnoch schrieb:

    eine kurzfristige Auswertungstabelle, dafür laufe ich z.B. mit einer Schleife durch die Rohdaten


    Das kannste aber in der GUI auch machen. Fügst im Form-Load meinetwegen deinem DataGridView eine Spalte hinzu und füllst diese mit den aus der Schleife geholten Werten.
    Dann hast du noch immer deine unveränderten Rohdaten - an's DGV gebunden und hast eine extra-Spalte mit der Extra-Wurst.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup: