Verknüpfte Tabellen speichern

  • VB.NET

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

    Verknüpfte Tabellen speichern

    Ich speichere aktuell verknüpfte Tabellen mit folgendem Code ab.

    VB.NET-Quellcode

    1. Try
    2. Me.Validate()
    3. Me.Tbl_TourenplanungBindingSource.EndEdit()
    4. Me.Tbl_TourenplanungTableAdapter.Update(Me.LoginfoDataSet.tbl_Tourenplanung)
    5. MsgBox("Tourenplan wurde gespeichert!",, "Loginfo")
    6. Catch ex As Exception
    7. MsgBox(ex.Message)
    8. End Try
    9. Try
    10. Me.Validate()
    11. Me.Tbl_TourenplanungDetailsBindingSource.EndEdit()
    12. Me.Tbl_TourenplanungDetailsTableAdapter.Update(Me.LoginfoDataSet.tbl_TourenplanungDetails)
    13. MsgBox("Tourenplan_Details wurde gespeichert!",, "Loginfo")
    14. Catch ex As Exception
    15. MsgBox(ex.Message)
    16. End Try


    Erst speichere ich die Detail-Tabelle anschließend die Master-Tabelle ab. Die Änderung passiert in der Detail-Tabelle.Der Code funktioniert. Aber ist er so in Ordnung, oder sollte man die Tabellen anders speichern?
    Erstmal sollte man zum speichern unbedingt eine eigene Methode schreiben - also mit Kopf- und Fuß-zeile.
    Keinesfalls sollte man versuchen, das mit so "verlorenen Zeilen" abzuhandeln, die ja irgendwo stehen können.
    Falls du eine Speicher-Methode hast, und hier nur deren Inhalt als "verlorene Zeilen" präsentierst, täte ich dringend empfehlen, zukünftig ganze Methoden zu posten, nicht iwelche unzusammenhängende Stückchen daraus.



    Dann täte ich empfehlen, die TryCatches wegzumachen. TryCatch fängt dir die bestmögliche (automatische, Standard-) Fehlermeldung weg und ersetzt sie durch iwas selbstgebasteltes, was nicht in 100 Jahren an die Fehler-Melde-Qualität herankommt, die du dir durch den TryCatch selbst weggenommen hast.
    Siehe TryCatch ist ein heißes Eisen



    So, jetzt erst zur eiglichen Frage:
    Ich empfehle immer, bei verknüpften Tabellen in der Datenbank die Löschweitergabe zu aktivieren.
    Und dann kann man eine generische Methode schreiben, die zwar sehr kompliziert ist, die aber imstande ist, alle Änderungen des Datasets fehlerfrei in die DB zurückzuschreiben.
    Ansonsten wird man schnell meschugge, wenn man für mw. 15 Tabellen in allen möglichen Kombinationen die Zufügungen, Änderungen, Löschungen in widerspruchsfreier Reihenfolge abspeichern will.
    Gugge Dataset->Db
    Ein weiterer Vorzug dieses generischen Vorgehens ist, dass man alle TableAdapter aus dem typisierten Dataset-Designer löschen kann - das ist eine ungeheure Menge generierten Codes, der so üflüssig ist wie er schlecht funktioniert.



    Du kannst auch mal deine bisherige Methode testen:
    lösch mal eine Tour, die bereits Details enthält, und füge anschliessend eine andere Tour (auch mit Details) hinzu, und speichere dann ab.
    Solche Updates von kombinierten Löschungen und Zufügungen sind quasi der HärteTest für Speicher-Methoden.



    Ach - und dann habich nochwas:
    Lass die Datenbank erstmal weg.
    Viel einfacher ists, den gesamten Datenbestand immer komplett ins Dataset zu laden/speichern und damit zu arbeiten - direkt von Platte.
    Weil dein Datenmodell wirst du noch oft ändern müssen, und das ist jedesmal ein Heiden-Gschiss, wenn da auch noch eine Datenbank dahinter-hängt, die auch noch geändert werden muss.

    Später, wenn deine Anwendung fertig ist, kannst du immer noch eine DB hinterlegen, und das Dataset dann aus der DB befüllen statt von Platte.
    Wobei ich bei einer TourenPlanungs-Software aber Zweifel hab, ob du jemals so viele Datensätze zusammenkriegst, dass eine Db ühaupt erforderlich wird.
    Weil in ein Dataset von Platte gehen locker so 20000 Datensätze (ausser, es sind massenhaft Bilder dabei).
    Siehe auch Daten laden und speichern



    Auch dein Datenmodell kann ich schon jetzt bekritteln: Es ist nicht sinnvoll, bei TabellenNamen Prefixe einzuführen. In einer DB gibts nix anneres als Tabellen - was soll also ein Prefix "tbl_" bringen, ausser dass daraus Code-Namens-Gräueligkeiten generiert werden, wie etwa Tbl_TourenplanungDetailsTableAdapter?
    Auch sollte man Tabellen singular benamen. Im Code geht man nämlich weniger mit den Tabellen um als vielmehr mit den einzelnen DataRows darin.
    Wenn nun die Tabelle plural flexiert, dann generiert der DatasetDesigner den einzelnen Datensatz ebenfalls plural - und das ist inhaltlich falsch.
    Weil etwa eine tbl_TourenplanungDetailsRow bedeutet vom Namen her mehrere Details, während in wirklichkeit nur ein einziges TourenDetail gemeint ist.
    Und noch ein: Suche immer möglichst kurze, aber noch klar verständliche Namen.
    In deinem Fall täten Tour und TourDetail vollkommen ausreichen, und du wirst es dir selber danken, wenn du nicht mehr mit so Wort-Ungetümen herumhampeln musst.
    Guter Code muss leserlich sein, und Wort-Monströsitäten sind auch etwas, was dem entgegensteht.



    Uih - da habich dich aber vollgetextet.
    Hmm - eiglich mache ich damit immer schlechte Erfahrungen.
    Weil nie gelingt es einem, wirklich alles gesagte aufzufassen und in seim Code einfliessen zu lassen.
    Das ist dann immer schnell frustrierend, wenn man sich bei Nachfragen dann wiederholen muss.
    Noch frustrierender ists natürlich, wenn Nachfragen gleich ganz ausbleiben - dann war die schöne "Doktor-Arbeit" ganz für Katz.

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

    Hab ich das mit dem Speichern dann so richtig verstanden?

    VB.NET-Quellcode

    1. Private Sub SpeichernTourenplan()
    2. Me.Validate()
    3. Me.Tbl_TourenplanBindingSource.EndEdit()
    4. Me.Tbl_TourenplanTableAdapter.Update(Me.LoginfoDataSet.tbl_Tourenplan)
    5. End Sub
    6. Private Sub SpeichernTourenplanDetails()
    7. Me.Validate()
    8. Me.Tbl_TourenplanDetailsBindingSource.EndEdit()
    9. Me.Tbl_TourenplanDetailsTableAdapter.Update(Me.LoginfoDataSet.tbl_TourenplanDetails)
    10. End Sub
    11. 'der Aufruf zum Speichern dann
    12. SpeichernTourenplan()
    13. SpeichernTourenplanDetails()



    Zum Datenbankmodel muss ich sagen: Ich hatte vorher das Programm in Access als Back-Frontend Version im Einsatz. Ich wollte das Programm jetzt, in Anlehnung des alten Programmes, in Visual Basic programmieren.

    Löschen ist für den Benutzer nicht vorgesehen. Die Touren zum löschen werden in der Datenbank als gelöscht markiert. Da es eine Mehrbenutzeranwendung ist, kam es oft vor, das Touren aus versehen gelöscht wurden, und dann doch wieder gebraucht wurden. Deshalb lösche ich die "gelöschten Touren" dann in der Sql-Datenbank mit einer Abfrage.

    Datenbank weglassen heisst, ich erstelle im Dataset-Designer die Tabellen, wie sie benötigt werden. Und wie kann ich sie dann hinterher an den SQL-Server anbinden?
    Ein paar Gedanken generelle Gedanken und Ansätze:
    1. Das Löschen von Daten sollte man sich genau überlegen, irgendwann insbesondere in Firmenumgebungen muss man noch mal an die alten Daten dran (die Revision, der Auditor).
    Für Betrachtungen aus der DSGVO, muss man sich dann mit dem Thema "Schwärzen" von Datensätzen auseinander setzen.
    2. Die Löschweitergabe an weitere Datensätze/Tabellen birgt immer die Gefahr, wenn diese falsch gesetzt sind, dass man auch Daten löscht, die man nicht löschen will.
    3. Die Aussage, in eine Datenbank gibt es nur Tabellen, möchte ich nicht so stehen lassen. Man sollte nicht die Leistungsfähigkeit von Views (Sichten), Stored Procedures, Trigger etc. unterschätzen.
    4. Alles im eigenen Arbeitspeicher zu halten, macht nur dann Sinn, wenn man auf einer Maschine arbeitet, aber dann brauche es ja auch kein DBMS, dass die Arbeit abnimmt.
    5. Abhängig von der genutzten DB, sollte man auch die Transaction-Routinen nicht außer Acht lassen. Dabei werden alle DB-Manipulationen in einer Routine zusammen gefasst. Wenn bei einer Manipulation etwas schief läuft, hat man die Möglichkeit, alles problemlos auf die Ausgangssituation zurückzusetzen.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

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

    broesel68 schrieb:

    Datenbank weglassen heisst, ich erstelle im Dataset-Designer die Tabellen, wie sie benötigt werden. Und wie kann ich sie dann hinterher an den SQL-Server anbinden?
    Naja, du musst im SqlServer die Tabellen erstellen, die durch das Dataset vorgegeben sind.
    Dafür hab ich mal einen Generator gebaut, dem gibt man ein Dataset an und einen Connectionstring auf eine vorhandene DB, dann generiert er Script und führt es im nächsten Schritt auch aus: Database-Generator

    broesel68 schrieb:

    Hab ich das mit dem Speichern dann so richtig verstanden?

    Jo, das mit dem Trycatch weglassen, und ganze Methoden schreiben ist richtig umgesetzt.
    Jetzt haste aber das Konzept geändert, und bist von "alles speichern" auf "jede Tabelle einzeln speichern" gewechselt.
    Wie gesagt: Es ist knifflig, aber machbar, einen Dataset-Speicherer zu coden, der beim Speichern immer das komplette Dataset mit der DB synchonisiert.
    Übers speichern einzelner Tabellen, einzelner Datensätze, Updates oder Inserts, blabla, braucht man sich dann keine Gedanken mehr zu machen.
    Wenn wolle, kann man den Speicherer nach jedem Zeilenwechsel aufrufen, aber ebensogut (und DB-Traffic-sparender) kann man einen "Save"-Button hinmachen, und dann wird alles gesaved, was zwischenzeitlich geändert wurde.
    Das sind die Pole: sofort speichern, oder nie speichern - nur auf Abruf. Dazwischen ist alles möglich, und auch die "Änderungen wurden festgestellt - Speichern?"-Abfrage ist eingebaut, die man kommen lassen kann, wenn man einen Bearbeitungsvorgang verlässt.

    Klar muss man sich Löschen gut überlegen.
    Das heisst aber nicht, dass man deswegen ein irreales Datenmodell ohne Löschweitergabe aufbaut.
    Wenn in Wirklichkeit ein Haus abgerissen wird, dann sind auch alle seine Zimmer weg.
    Wenn man solch in einem Datenmodell darstellt, wäre ich strikt dafür, dass dort die Zimmer ebenfalls via Löschweitergabe automatisch weg sind, sollte das Haus gelöscht werden - das ist eine Frage von Daten-Konsistenz: Ein Zimmer ohne Haus gibt es nicht.
    Dem User das Löschen nicht bereitzustellen ist Aufgabe der Benutzerführung der Client-Software.

    Wie gesagt: Wenn du neu entwickeln kannst, lass die DB erstmal weg, dann bist du im Ändern des Datenmodells (was während einer Entwicklung nie ausbleibt) wesentlich flexibler. So kannst du auch "kleine" Designfehler (wie zB unleserliche Wortungetüme) frühzeitig ausbügeln, die dich sonst dein Leben lang ärgern.
    Eine DatasetOnly aufgebaute Anwendung kannste sogar zippen und hier anhängen, dann kann man die mal angugge.
    zum zippen kannste zB dieses Tool verwenden: SolutionExplorer - OpenSource
    Damit kann man auch sehr bequem Backups erstellen, weil während einer Entwicklung macht man immer auch mal was kaputt.

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