Richtiges Befüllen mehrere DatenTables mit Beziehung

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

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

    Richtiges Befüllen mehrere DatenTables mit Beziehung

    Servus Leute,

    wie befüllt man ein Dataset, in dem 2 Datatables existieren und eine 1:n Relation zueinanderhaben richtig?

    Die Daten ziehe ich mir aus einer Datei, welcher in einer List(of String) gespeichert werden.

    Mir würde es nur so einfallen, das ich mittels einer For Each-Schleife die Daten in der ersten Datatable("Products") speichere, dann eine Function aufrufe, die die DataTable ("Products") nach z.B. der EAN durchsucht, mir die ID von dem gefundenen EIntrag übergibt und diese Trage ich dann in der spalte "ProductID" ein und befülle die weiteren Spalten mit meinen Daten.
    quasi so:

    VB.NET-Quellcode

    1. Sub GetData() 'alle einträge in einer List(Of String) speichern
    2. Dim _x As New List(Of String)(System.IO.Directory.GetFiles("B:\Bearbeitet\", "*.json", System.IO.SearchOption.AllDirectories))
    3. For Each line As String In _x 'alle einträge aus der List(Of String) durchgehen
    4. CreateXML(ReadData(line))' Create XML= in DataSet eintragen, ReadData= Die benötigten Daten aus der Datei lesen
    5. Next
    6. End Sub
    7. Sub CreateXML(ByRef line As List(Of String))
    8. Dim tr As New DataSet1.ProductsDataTable
    9. Dim Title As String = line(1)
    10. Dim Description As String = line(8)
    11. Dim Gewicht As String = line(6)
    12. Dim Breite As String = line(11)
    13. Dim Höhe As String = line(13)
    14. Dim Tiefe As String = line(12)
    15. Dim Hersteller As String = line(3)
    16. Dim _Hersteller_Nummer As String = line(5)
    17. Dim _Hersteller_URL As String = line(4)
    18. Dim Image As String = line(13)
    19. Dim EAN As String = line(7)
    20. Dim TechnischeDaten As String = line(9)
    21. tr.AddProductsRow(Title, Description, Höhe, Breite, Tiefe, Gewicht, Hersteller, _Hersteller_URL, _Hersteller_Nummer, TechnischeDaten, Image)
    22. 'hier dann die Function aufrufen um die ID von dem letzten eintrag zu erhalten und dann die 2te DataTable (Deliver) eintragen
    23. End Sub


    trix0 schrieb:

    wie befüllt man ein Dataset, in dem 2 Datatables existieren und eine 1:n Relation zueinanderhaben richtig?
    Man fügt immer erst einen ParentDatensatz der ParentTable hinzu, danach die ChildDatensätze des ParentDatensatzes der ChildTable.

    Man kann auch zunächstmal alle ParentDatensätze zufügen, und später dann die ChildDatensätze.
    Letzteres ist aber bisserl aufwändiger, weil man muss evtl. für jeden ChildDatensatz den richtigen Parent heraussuchen.
    Okay, also ich mache es gerade so:

    VB.NET-Quellcode

    1. tr.AddProductsRow(Title, Description, Höhe, Breite, Tiefe, Gewicht, _Hersteller_Nummer, TechnischeDaten, Image)
    2. nBeziehungDeli(tr.Item(tr.Count - 1), "api", 0.04, 0.04 * 1.25, "IrgendeineNummer")
    3. Sub nBeziehungDeli(ByRef ID As DataSet1.ProductsRow, ByRef Name As String, ByRef Einkauf As Double, ByRef Verkauf As Double, ByRef Nummer As String)
    4. Dim tr As New DataSet1.DeliverDataTable
    5. tr.AddDeliverRow(ID, Name, Einkauf, Verkauf, Nummer)
    6. End Sub


    wäre das so in Ordnung oder habe ich hierbei ein Denkfehler?
    ByRef ist auf jeden Fall verkehrt.
    Ansonsten kannst du deine Frage am besten selbst beantworten: Funktionierts?

    Ansonsten kannste dich auch hier umgucken:
    vier Views-Videos
    In den Codesamples dazu werden auch Datasets codeseitig befüllt.

    Also wenns funktinoiert würde ich diese Verbesserung vorschlagen:

    VB.NET-Quellcode

    1. Dim rwProd = Dataset1.Products.AddProductsRow(Title, Description, Höhe, Breite, Tiefe, Gewicht, _Hersteller_Nummer, TechnischeDaten, Image)
    2. Dataset1.Deliver.AddDeliverRow(rwProd, "api", 0.04, 0.04 * 1.25, "IrgendeineNummer")
    Also im Grunde doch äusserst banal - oder?
    Einfach die gegebenen Methoden nutzen unter Befolgung der Regeln der Sprache VB.Net - da kann man eiglich nichts falsch machen.

    Natürlich kann man jede Menge falsch machen, wenn man die Sprache nicht kennt.
    Du scheinst nicht die Bedeutung von ByRef zu kennen, und nicht die Bedeutung von New.
    Oder kannst du erklären, was du mit deren Verwendung bezwecktetest?

    Und dass die AddBlaBlaRow-Methoden die frisch geaddete BlaBlaRow returnen ist dir auch entgangen.
    Also lad dir ein gute Online-Buch herunter, von Kühnel/Leibhard oder von Löffelmann, und informier dich.
    Vermeide Bücher von Theiss - der macht alle Fehler, die man in VB.Net nur verbrechen kann.

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

    Also

    VB.NET-Quellcode

    1. ByRef
    übergibt den Wert So, das der Übergebene Wert verändert werden kann.
    z.B.:

    VB.NET-Quellcode

    1. Sub WertVerändern(ByRef x As String)
    2. x = "Hallo"
    3. End Sub

    Egal, was davor in der übergebenen Variablen steht, würde jetzt mit "Hallo" ersetzt. ByVal wird dieser gleich bleiben.

    So in etwa würde ich es beschreiben.

    Bei

    VB.NET-Quellcode

    1. New
    meinte ich, das man damit zuerst die Klasse initialisiert, um dann auf deren Funktionen zugreifen zu können
    Wenn Du das über ByRef weißt, wozu dann Sub nBeziehungDeli(ByRef ID As DataSet1.ProductsRow?
    Was dazu kommt: der Methodenname ist echt übel und den parameter ID zu nennen - also wenn Du Dich damit mal nicht selber in die Verwirrung treibst …
    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.

    trix0 schrieb:

    Also

    VB.NET-Quellcode

    1. ByRef
    übergibt den Wert So, das der Übergebene Wert verändert werden kann.
    z.B.:

    VB.NET-Quellcode

    1. Sub WertVerändern(ByRef x As String)
    2. x = "Hallo"
    3. End Sub

    Egal, was davor in der übergebenen Variablen steht, würde jetzt mit "Hallo" ersetzt. ByVal wird dieser gleich bleiben.

    So in etwa würde ich es beschreiben.
    Zwei Probleme mit deiner Erklärung:
    1) Bischen unsauber erklärt - weil natürlich kannst du den übergebenen Wert auch bei ByVal ändern:

    VB.NET-Quellcode

    1. Sub WertVerändern(ByVal x As String)
    2. x = "Hallo"
    3. End Sub
    auch hier wird in x "Hallo" eingetragen.

    2) In deiner Methode aus Post#3 willst du den Wert aber doch garnet ändern!
    Wenn man das (ziemlich gefährliche!) ByRef - Feature nicht benötigt, dann sollte man es keinesfalls einsetzen!
    Also einfach weglassen, und du bist auf der sicheren Seite.



    trix0 schrieb:


    Bei

    VB.NET-Quellcode

    1. New
    meinte ich, das man damit zuerst die Klasse initialisiert, um dann auf deren Funktionen zugreifen zu können
    ne - initialisieren ist was anderes. New erzeugt ein neues Objekt - deshalb heisst es ja auch New.
    Und das ist hier ja ganz unerwünscht, du willst ja nicht für jede hinzuzufügende Zeile eine eigene DeliverDataTable erzeugen, dann hast du am Ende einen Riesen-Haufen DeliverDataTables, und jede enthält genau einen Datensatz.
    Und die DeliverDataTables fliegen irgendwo herum, jedenfalls in deim Dataset sind sie nicht - in deim Dataset ist nur eine DeliverDataTable drinne, nämlich diejenige, die schon von Anfang an drinne war.
    Und nur in diese eine DeliverDataTable solltest du Datensätze zufügen - keinesfalls reihenweise neue DeliverDataTables erzeugen - halt wie ichs in post#4 vorgemacht - ist ja ganz einfach.
    okay danke. das mit

    VB.NET-Quellcode

    1. NEW
    habe ich jetzt verstanden.

    zwecks meiner erklärung.
    ich meinte es so, um es näher zu erläutern:

    VB.NET-Quellcode

    1. Sub Aufruf()
    2. Dim veränderteVariable as String = "Test"
    3. WertVerändern(veränderteVariable)
    4. End Sub
    5. Sub WertVerändern(ByRef x As String)
    6. x = "Hallo"
    7. End Sub


    dann würde

    VB.NET-Quellcode

    1. veränderteVariable
    nach dem Aufrunf den Wert "Hallo" besitzen.
    Jo, also verstehst du ByRef durchaus richtig.
    Allerdings ist in deim konkreten Fall genau dieses Feature total unerwünscht, und giftig - also hier keinesfalls! ByRef verwenden.
    Da bräche doch das Chaos aus (in post#2), wenn die übergebene ProductsRow auf einmal eine andere ist als diejenige, die du übergeben hast.
    (also wenn du schrübest: ID = new ProductsRow() oder son Käse)
    Aber tatsächlich weist du dieser ProductsRow ja gar keinen neuen Wert zu - es bleibt ja dieselbe.
    Wenn es aber dieselbe bleiben soll - und das soll es ja - dann ist das ByRef ungenutzt, unangebracht, unnütze und nur eine mögliche Fehlerquelle.
    lass es weg.