DB Extensions

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

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

    DB Extensions

    Hallo Community und EDR,

    ich arbeite schon seit einigen Jahren mit den von EDR erstellten DB-Extensions. Es läuft alles wunderbar und deswegen habe ich auch nie nach Änderungen oder Updates gesucht.
    Doch nun ist es soweit, dass ich auf ein Problem gestossen bin
    "Joiner unterstützt keine mehrspaltigen DataRelations"

    also fing ich an zu suchen, fand folgenden Post https://www.vb-paradise.de/index.php/Thread/106984-ClearBeforeFill-bei-DB-Extensions und dabei viel mir auf, dass der Code um Einiges von meiner, wahrscheinlich älteren, Version abweicht.
    Somit ergeben sich zwei Fragen:
    1. Gibt es eine Lösung/Update zu oben genannter Meldung/Einschränkung?
    2. Kann man die aktuellste Version der DBExtensions irgendwo runterladen und enthält diese eine Lösung?
    Vielen Dank für eure Hilfe
    Wenn ich mich recht erinnere ist Joiner ein Dingens, was anhand des Datasets Sql-Queries an die Datenbank generiert.
    Das ist echt schon ein sehr advanced Einsatzgebiet der DBExtensions.
    Jo, und da isses eben so, dass Joiner mit mehrspaltigen Relationen nicht umgehen kann.
    Also entweder du änderst dein Datenmodell dahingehend, dass Relationen einspaltig sind, oder du formulierst deine Sql-Statements selber.

    So ins Blaue gesprochen.
    Gibts zu dem Fehler keinen Code, wo man sieht, was du da eiglich treibst?
    Also das ganze Dataset ist viel zu groß um es auf ein Bild zu bekommen, deswegen habe ich nur den relevanten Ausschnitt als Bild angefügt.
    Das Ganze dreht sich um Golfplätze und ich weiß nicht inwieweit ihr euch damit auskennt. Deswegen ein paar Erklärungen
    Ein Golfplatz besteht aus Löchern (meistens 18); jedes Loch hat normalerweise mindestens drei Teilbereiche (Abschlag, Fairway und Grün)
    Somit ergibt sich folgendes Datenmodell:
    Die Teilbereiche sind in der Tabelle "Area" erfasst und jedes Loch in der Tabelle "Hole", daraus ergibt sich die Tabelle "Surface", wo die Flächen der einzelnen Bereiche, pro Loch erfasst werden.
    Beispiel:
    Grün, Loch 1, 600m²
    Grün, Loch 2, 450m²
    .
    .
    Fairway, Loch 1, 10250m²
    Fairway, Loch 2, 13731m²
    .
    .
    usw

    nun folgendes Szenario/Problem:
    In der Tabelle "AgrTask" werden Arbeiten für jede "Area" erfasst und danach kann ausgewählt werden auf welchen Löchern (Tabelle "AgrTaskHole") diese Arbeiten ausgeführt werden sollen. Soweit so gut und dies Alles funzt.

    Jetzt würde ich gerne den Surface-Wert (roter Pfeil) der sich aus HoleID und AreaID eindeutig ergibt, über eine Relation in die "AgrTaskHole" Tabelle einfügen. Somit könnte ich eine Sum Spalte in die "AgrTask" einfügen, die mir die Summe der Fläche auswirft.
    Die Relation lässt sich auch erstellen, nur beim laden gibt's dann oben genannten Abflug...

    Hoffe es gibt eine einfache Lösung dafür...oder einen anderen Ansatz, den ich nur nicht sehe oder kenne.
    Auf jeden Fall schon mal Danke
    Bilder
    • Surface.jpg

      164,13 kB, 956×573, 128 mal angesehen
    die Spalte Surface.SurfaceID - kommen da Dopplungen vor?
    Wenn nicht, ist .SurfaceID doch der geeignete PrimKey-Kandidat, und die anneren beiden Spalten sollten nicht PrimKey sein.

    Entsprechend sollte AggrTaskHole aussehen:
    AggrTaskHoleID als PK hinzufügen, die anneren beiden sollen nicht Bestandteil des PK sein.
    Jdfs wenn du mittm Joiner daraus Sql-Statements generieren willst.

    Übrigens empfehle ich sehr, PKs immer 'ID' zu benennen. Der Erkennungswert ist hoch, und Es kommt dabei zu keinen Namenskonflikten, auch wenn in mehreren Tabellen die Spalte 'ID' auftaucht. Weil eine Spalte immer zu einer bestimmten Tabelle gehört, und Spalten ühaupt nicht unabhängig von ihrer Tabelle addressierbar sind.
    Deshalb reicht als PK-Spalten-Name 'ID'.
    Und so hast du auch eine klare Namenskonvention auch für den FK - nämlich TabellenName+ID - wie du's ja auch machst.
    Und wenn man bei meiner Namenskonvention sagt: 'HoleID' dann ist klar, dass das ein FK ist.
    Sagt man aber 'Hole.ID' - dann ists klarerweise ein PK.
    Ich verstehe nur nicht, inwieweit mir das helfen soll, denn auf meine Frage bist du gar nicht eingegangen.
    Der Joiner verarbeitet alles ohne Probleme und das Programm laedt und laeuft auch.

    Ich moechte nur ein paar Erweiterungen einbauen und dafuer moechte ich den Surface, der sich aus AreaID und HoleID eindeutig ergibt in die AgrTaskHole Tabelle als Parent Expression einfuegen. Dafuer brauche ich aber eine Relation mit eben diesen zwei Spalten.

    Uebrigens fuegt er diesen Schluessel nicht nur fuer PK hinzu sondern auch fuer andere Schluessel, um z.B. Doppelungen(AreaID und HoleID muessen unique sein; und ja, somit koennte man auf die PK verzichten) zu unterbinden, ein.

    TS71M schrieb:

    auf meine Frage bist du gar nicht eingegangen.
    Nanu?
    Ich dachte, das Problem sei des Joiners Fehlermeldung von wegen mehrspaltiger Relationen.
    Und mehrspaltige Relationen entstehen aus mehrspaltigen PrimaryKeys.
    Und mein Lösungsvorschlag ist, im Datenmodell mehrspaltige PrimaryKeys zu ersetzen durch einspaltige.
    Da muss ich leider widersprechen. Die Spalten AreaID und HoleID haben den Schlüssel nur wegen Unique und sind nicht PK. Ich möchte eine Relation zwischen AgrTaskHole und Surface einrichten mit den Schlüsseln AreaID und HoleID und dort fliegt er dann. Ohne diese Relation ist alles gut.
    Anbei noch ein paar Bilder zur Verdeutlichung.
    Im Moment sehe ich leider keine Moeglichkeit dies auf eine Spalte zu reduzieren.
    Bilder
    • RelationDetail.jpg

      24,39 kB, 176×342, 95 mal angesehen
    • SurfaceColumn.jpg

      31,94 kB, 335×289, 84 mal angesehen
    • Relation.jpg

      68,92 kB, 602×589, 92 mal angesehen

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

    TS71M schrieb:

    Im Moment sehe ich leider keine Moeglichkeit dies auf eine Spalte zu reduzieren.
    Jo, dann weiss ich auch nicht.
    Da müsste man den Joiner erweitern, dasser dann doch auch mehrspaltige Relationen unterstützt, wenner Sql generiert.
    Aber das ist eh schon irrsinnig kompliziert, wennich mich recht erinnere.

    Oder wie gesagt du verzichtest halt an der Stelle auf dieses DbExtension-Feature, und bastelst stattdessen händisch formuliertes Sql ein.
    Kannst du eiglich die Code-Stelle zeigen, wo das auftritt? Muss ja iwie eine Table.Fill-Extension sein, die mehrere Tabellen einbezieht, nämlich mindest. AgrTaskHole und Surface - oder?



    TS71M schrieb:

    Im Moment sehe ich leider keine Moeglichkeit dies auf eine Spalte zu reduzieren.
    Ich aber doch: Spendir der AgrTaskHole-Tabelle eine FK-Spalte auf Surface.SurfaceID und richte die entsprechende Relation ein.
    Oder warum sollte das nicht gehen?

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

    ErfinderDesRades schrieb:

    Ich aber doch: Spendir der AgrTaskHole-Tabelle eine FK-Spalte auf Surface.SurfaceID und richte die entsprechende Relation ein.
    Oder warum sollte das nicht gehen?

    Theoretisch wäre dies möglich, da die AgrTaskHole Tabelle aber bereits über 4800 Einträge hat, wäre dies ziemlich aufwendig die entsprechende SurfaceID rauszusuchen und zu Fuß einzufügen.
    Auch wirkt es ein wenig wie ein B-Lösung, da diese Spalte nicht nötig wäre, sondern diese Relation nur bereits vorhandene Daten in eine andere Tabelle übertragen soll (berechnete Spalte).

    Gibt es bei Relationen denn nicht auch so etwas, wo man einzelne ausschließen kann, wie bei den Tabellen mit dem persist-Befehl?
    Oder kann ich die Relation nach dem Start des Programms manuell einfügen?

    Die sql Abfrage ohne Relation

    SQL-Abfrage

    1. SELECT `AgrTaskHole`.* FROM ((`Area` INNER JOIN `AgrTask` ON (`Area`.`ClientID`=@p0 AND `Area`.`AreaID`=`AgrTask`.`AreaID`)) INNER JOIN `AgrTaskHole` ON (`AgrTask`.`AgrTaskID`=`AgrTaskHole`.`AgrTaskID`))
    2. 6 @p0-ClientID: 23


    Wenn ich die Relation einfüge bekomme ich nur ein

    Quellcode

    1. Exception thrown: 'System.Exception`1' in DBExtensions.dll

    und folgende Meldung:
    Bilder
    • Joiner.jpg

      27,93 kB, 417×239, 91 mal angesehen

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

    Das sieht mir zuallererst nach unsachgemäßer TryCatch-Verwendung aus.
    Suche alle TryCatchens, wo im Catch-Block nichts passiert ausser der Ausgabe der Fehlermeldung.
    Entferne alle diese TryCatchens - weil sind Müll, alle!
    Anschliessend wird der Debugger dir wieder vernünftige Fehlermeldungen geben, und dabei an genau der Zeile anhalten, wo der Fehler auftritt.
    Kurz gesagt: Dann macht der Debugger wieder seinen Job, und du kannst die Fehler finden.
    da ist kein try catch ?(

    VB.NET-Quellcode

    1. Public Shadows Function Add(xpr0 As String, rl As DataRelation, Optional xpr1 As String = "") As Joiner
    2. If rl.ChildColumns.Length > 1 Then Throw Me.Exception("Joiner unterstützt keine mehrspaltigen DataRelations")
    3. MyBase.Add({New ColumnInfo(rl.ParentColumns(0), xpr0, _Quote), New ColumnInfo(rl.ChildColumns(0), xpr1, _Quote)})
    4. Return Me
    5. End Function
    ja, da musst du den Stacktrace aufwärts untersuchen - irgendwo wird die dort geworfene Meldung offsichtlich gecatcht.
    Und es ist Unfug, Joiner-Exceptions zu catchen, weil die kannste nicht behandeln.
    Ich sag ja: unsachgemässe TryCatcherei.
    Wenn du mehr drüber wissen willst:
    TryCatch ist ein heißes Eisen

    Und ein zweites sag ich ebenfalls ein 2. Mal: Schmeiss alle deine TryCatchens raus, die derlei Unfug treiben.

    Merke:
    Die Fehlermeldung als Messagebox ausgeben ist keine Fehlerbehandlung.
    Das ist nur Debugger-(Selbst-)Sabotage.