DataSet Löschregel cascade zu anderen Tabellen

  • VB.NET

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

    DataSet Löschregel cascade zu anderen Tabellen

    Hallo

    Ich hätte da mal eine Frage

    Meine SQL Datenbank hat 3 Tabellen

    1) Auftraggeber
    2) Standorte
    3) Objekte

    Die Tabelle Objekte hat 2 Fremdschlüssel, einer verweist auf die Id des Auftraggebers und der andere auf die Id des Standortes.

    Zusätzlich habe ich in den Standorten eine Fremdschlüssel beziehung zu den Id's der Auftraggeber. (siehe Bild) ---> ist diese Fremdschlüssel beziehung überhaupt notwendig?

    Alle Verweise sind in den Regeln auf Cascade eingestellt.

    Ein Objekt MUSS immer einen Auftraggeber und einen Standort haben.




    Als Beispiel: Ich habe einen Auftraggeber der wiederum hat 1 Standort unter dem 3 Objekte existieren. Würde beim löschen dieses Auftraggebers auch alles mit einer Beziehung dazu gelöscht werden? Oder würde das löschen verhindert, weil das DataSet weiß das da noch sachen hinten dran hägen?
    Bilder
    • Screenshot 2022-04-04 210519.png

      51,57 kB, 854×737, 57 mal angesehen

    Ostseebengel74 schrieb:

    Alle Verweise sind in den Regeln auf Cascade eingestellt.
    Das ist unkorrekt formuliert, aber doch klar erkennbar, dass du meinst: "Alle Relationen haben DeleteRule.Cascade eingestellt" ("Verweis" ist in Teilen was ähnliches, aber doch bischen was anderes (und sowas sind mit die schlimmsten Begriffs-Verwirrungen ;) ))
    Ansonsten ist (durch die klare Begrifflichkeit) deine Frage doch beantwortet - "DeleteRule.Cascade" kann doch nichts anderes heissen als Löschweitergabe, und was das wiederum heisst, ist doch selbsterklärend, odr?

    Hättest du keine Löschweitergabe - dann würde deine Auftraggeber-Löschung zur Verletzung der Integrität führen, und vom Dataset abgelehnt.



    Du kannst übrigens Relationen sogar ohne ForeignKey-Constraint einrichten, d.h. ohne Überprüfung der referenziellen Integrität.
    Dann kannste Auftraggeber löschen und Kunde und Objekt kratzt das nicht.
    Tätst dir aber keinen Gefallen damit.

    Ich empfehle immer mit ForeignKey-Constraint, und sogar mit Löschweitergabe - selbst wenn Löschungen nicht vorgesehen sein sollen.
    Löschungen verhindern ist ggfs. Aufgabe des Programms.
    Das muss es sowieso leisten, weil damit umgehen, wenn ein Dataset (oder gar eine Datenbank) eine Löschung ablehnt (also wenn Kind schon in Brunnen) ist deutlich aufwändiger.
    Aber ohne Löschweitergabe modellieren kann man auch für sinnvoll halten, besonders im ProduktivBetrieb.
    Während der Entwicklungszeit ists jedenfalls gelegentlich vorteilhaft, seine Testdaten auch mal löschen zu können, ohne gesteigerten Aufwand des händischen Beachtens der Daten-Integrität.



    Was ich dir noch sehr empfehle: Probiers aus.
    Das kann durchaus Spass machen, ein Test-Progrämmchen basteln und gucken, wie sich das System unter verschiedenen Konfigurationen verhält.
    Und ist das bessere Lernen, wenn Theorie und Praxis zusammenfinden.

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

    Oder auch Daten laden und speichern
    Es ist nämlich vom Lernen her höchst ineffektiv, bei einer Datenverarbeitungs-Anwendung sich gleich die sehr hohe Komplexität einer Datenbank ans Bein zu binden.
    Dem Zugriff auf Datenbank sollte unbedingt vorrausgehen, dass man sich mit relationaer Modellierung, Databinding, Usercontrols, Layout gut auskennt.
    Also die ganze Anwendung sollte man immer (gilt auch für Kenner der Materie) erstmal ohne Datenbank ausprogrammieren, und statt Datenbank einfach eine Dataset-xml-Datei verwenden.
    Das ist bereits Stoff reichlich genug, aber wenn man gleichzeitig mit DB einsteigt hat man ein zweites fast ebenso komplexes Thema am Hals, und Komplexitäten addieren sich nicht, sondern sie multiplizieren sich.
    Einen kompletter Lernplan gibt hier: Datenverarbeitungs-Vorraussetzungen
    (Und du stehst da ziemlich am Anfang, ich hab Code von dir gesehen, da ist noch nichtmal Option Strict On aktiviert.)

    ErfinderDesRades schrieb:

    (Und du stehst da ziemlich am Anfang, ich hab Code von dir gesehen, da ist noch nichtmal Option Strict On aktiviert.)


    Hallo Erfinder des Rades... meinst du mich damit???

    Ja, ich bin mir durchaus bewusst das ich nicht viel weiß. Deswegen frage ich auch soviel. Hab mir jetzt alle Postings und Videos von Dir zu diesem Thema reingezogen. Langsam begreife ich ;) ...
    Ich habe mein Programm erst einmal auf XML umgestellt...

    Danke für die nützlichen Hinweise

    Noch eine Frage am Rande...

    Quellcode

    1. KonsoleDataSet.WriteXml(Application.StartupPath & "\BackupDB.xml")
    2. KonsoleDataSet.WriteXml(Application.StartupPath & "\BackupDB_temp.xml", XmlWriteMode.WriteSchema)


    ist das setzen von WriteSchema erforderlich?




    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Ostseebengel74“ ()

    Ostseebengel74 schrieb:

    ist das setzen von WriteSchema erforderlich?

    wie ich sagte:

    ErfinderDesRades schrieb:

    Probiers aus.


    Und guck auch in die entstehenden Dateien hinein.
    Tatsächlich kannte ich die zweite Variante garnet, hab jetzt im Objectbrowser nachgeguckt, wasses damit auf sich hat. Ich verrats aber nicht, weil du ja auch selbst nachgucken kannst.
    Kann ich sehr sehr empfehlen, sich mit derlei Fragen immer erstmal vertrauensvoll an den Objectbrowser zu wenden.

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

    Hast du in die Dateien geguckt?
    Hast du auch die anderen XmlWriteMode-Werte ausprobiert?
    Und im Objectbrowser haste wohl nicht wirklich geguckt, zumindest ohne "browsen". Weil wie gesagt, da steht was dazu.
    (Ich hoffe nur, dass es richtig ist, ich hätte eigentlich schon Unterschiede bei den Dateien erwartet)
    Wenn ich

    Quellcode

    1. Writemode.IgnoreSchema
    setze kommt natürlich etwas anderes raus.

    Quellcode

    1. KonsoleDataSet.WriteXml(Application.StartupPath & "\BackupDB.xml")
    2. KonsoleDataSet.WriteXml(Application.StartupPath & "\BackupDB_temp.xml", XmlWriteMode.WriteSchema)


    Beide XML Dateinen sind gleich groß und enthalten auf den ersten Blick die selben Daten.
    Jo, sowas gibts oft.
    Eine Methode ist wie hier mehrfach überladen, und die Überladungen unterscheiden sich nur am zusätzlichen Parameter.
    Dann ist die Methode ohne den zusätzlichen Parameter die meistverwendete, einfacher aufzurufende.
    Intern ruft sie dann die mit dem zusätzlichen Parameter auf, wobei sie einen hardcodet Standard-Wert übergibt.
    Also im Grunde wird immer die mit beiden Parametern aufgerufen, nur wenn man ihn weglässt, wird ein Standard-Wert eingesetzt.
    Beim Erstellen einer neuen Abfrage über den Table Adapter Manager, kommt ja immer dieses Fenster. (siehe Bild)

    Der oberste Punkt ist mir klar, bei dem unteren bin ich mir nicht so sicher. Wird da eine Kopie der Tabelle in meinem DataSet erstellt? Wenn ja ist diese Abfragbar bzw. kann die SQL Anweisung für diese anders sein?
    Bilder
    • Screenshot 2022-04-10 114945.png

      27,54 kB, 659×518, 55 mal angesehen
    Kannst du inzwischen mit dem Objectbrowser umgehen?
    Weil dann kannstes ausprobieren, und guckst dann im OB nach, welche Methoden bei welcher Einstellung im TableAdapter generiert werden, und wie die ticken.
    Die Namen kann ich schon verraten: die eine heisst FillByAktiv(), und die andere GetDataBy().
    Nun gilt es, den Assistenten fertigstellen zu lassen, und dann im OB gucken, was er gemacht hat.
    (Du kannst die Namen auch ändern, aber warum? sind doch gute Methoden-Namen, die sagen, was sie tun)

    Ostseebengel74 schrieb:

    bzw. kann die SQL Anweisung für diese anders sein?
    Das geeeht auch, dürfte aber ins Chaos führen.
    Stattdessen ist vorgesehen, dass du dem TableAdapter weitere Abfragen hinzufügst (natürlich mit dem Sql deiner Wahl)
    Wenn ich ehrlich bin ist mir trotz ansehen deines Videos, das ganze da zu Kryptisch, also was den Objekt Browser angeht.

    Quellcode

    1. <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    2. Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0"), _
    3. Global.System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter"), _
    4. Global.System.ComponentModel.DataObjectMethodAttribute(Global.System.ComponentModel.DataObjectMethodType.Fill, false)> _
    5. Public Overloads Overridable Function FillByAktiv(ByVal dataTable As KonsoleDataSet.mitarbeiterDataTable) As Integer
    6. Me.Adapter.SelectCommand = Me.CommandCollection(1)
    7. If (Me.ClearBeforeFill = true) Then
    8. dataTable.Clear
    9. End If
    10. Dim returnValue As Integer = Me.Adapter.Fill(dataTable)
    11. Return returnValue
    12. End Function
    13. <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    14. Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0"), _
    15. Global.System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter"), _
    16. Global.System.ComponentModel.DataObjectMethodAttribute(Global.System.ComponentModel.DataObjectMethodType.[Select], false)> _
    17. Public Overloads Overridable Function GetDataByAktiv() As KonsoleDataSet.mitarbeiterDataTable
    18. Me.Adapter.SelectCommand = Me.CommandCollection(1)
    19. Dim dataTable As KonsoleDataSet.mitarbeiterDataTable = New KonsoleDataSet.mitarbeiterDataTable()
    20. Me.Adapter.Fill(dataTable)
    21. Return dataTable
    22. End Function


    FillByAktiv führt bei mir folgende Abfrage aus:

    SQL-Abfrage

    1. SELECT Id, Aktiv, Account, Vorname, Nachname, Position, Telefon1, Telefon2, Email, Info1, Info2, Info3, Rechte, RechteLevel, Passwort, Konsole, Login, Logout, ComputerName, ComputerRes, Logins, EBladenPfad, EBspeichernPfad, EBname, SQLname, SQLpw
    2. FROM mitarbeiter
    3. WHERE (Aktiv = 1)


    im obigen Code aus dem Objekt Browser sehe ich aber kein FillByAktiv sondern nur Fill. Fill liest aber ALLES ein und es gibt keine WHERE klausel.







    Bilder
    • Screenshot 2022-04-10 133336.png

      39,11 kB, 1.371×942, 39 mal angesehen

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

    komisch.
    Wenn bei mir eine Methode FillByAktiv existiert, und ich im OB nach Fill suche, dann wird die auch gefunden.
    hattest du vlt. noch nicht kompiliert?



    Aber ansonsten hast du doch kein Problem - die gezeigten Methoden sind gut benamt, und tun doch, was sie sollen - oder?

    Wenn du weitere möchtest, kannst du ja weitere hinzufügen.

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