Relation wird in Datenquellen nicht angezeigt

  • VB.NET

Es gibt 28 Antworten in diesem Thema. Der letzte Beitrag () ist von Marsianer.

    Relation wird in Datenquellen nicht angezeigt

    Salut.

    Ich bastel derzeit an meiner ersten DB-Anwendung (is auch mein erstes VB-Projekt) und fummel grad an meinen Datenbindungen rum, wie der Pennäler am BH seiner ersten Freundin. Folgendes Szenario:
    SQL-ServerCE als lokale DB, Projekt ist eine Finanzdatenbank (Ja, ich weiß, davon gibts schon tausende. Aber nein, ich will das genau so hinschrauben, wie ich es haben will. Und außerdem will ich ja damit auch das VB-Proggen lernen).
    Im Prinzip eine Tabelle mit den eigentlichen Buchungen sowie weitere Tabellen, in denen Werte stehen, die der Benutzer dann über schicke Comboboxen in seine Buchungen einklicken kann (sowas wie Fälligkeit, Zahlungsarten... ist nicht so von Belang hier).
    Bisher hat es prima funktioniert
    Dataset erstellt.
    Relations definiert. Alle Tabellen binden sich über id-Spalten. Alle Detailtabellen sind der Buchungstabelle übergeordnet (1:n)
    Forms für Detailtabellen gebastelt (ging superleicht in VB)
    Hauptform gebastelt... alles schick für die Basisdaten, auch Detailtabellen über Combos eingebunden, die Werte werden als Integer im Buchungsdatensatz abgelegt. Datenbindung einwandfrei über Bindingsources.

    Aber dann:
    Da ich weitere Daten an so eine Buchung anklemmen will (die aber nicht für jede Buchung von Belang sind) habe ich weitere Tabellen, in denen sie abgelegt werden. Die sind verknüpft mit der Buchungstabelle über deren ID, also ist diesmal die Buchungstabelle übergeordnet. Auch dafür habe ich im DataSet entsprechende Relations (da mit Löschweitergabe) definiert.

    Habe in meinem Buchungsformular ein Tabcontrol definiert mit mehreren Tabpages. Jede Page für eine dieser Zusatztabellen. Und dann ging der Zirkus los. Normalerweise würde ich sagen, ich ziehe aus den Datenquellen die Relation Buchung/[Zusätzliche Tabelle] einfach in die Tabpage, formatiere das entstehende DGV und schick ist. Ist aber nicht schick. Meine Datenquellen zeigen mir diese speziellen Relations nicht an! Die Relations, in denen meine Buchungstabelle untergeordnet ist, werden bei den jeweiligen Detailtabellen angezeigt, aber nicht die, wo meine Buchungstabelle übergeordent ist :cursing: .

    Habe ein DGV über die eigentliche Datatable einer Zusatztabelle eingebaut, aber Bingo: geht natürlich nicht. Bekomme eine Exception, weil die id des Buchungsdatensatzes nicht automatisch eingetragen wird. Was nicht anders zu erwarten war.

    Hat jemand eine Idee, warum in meinen Datenquellen diese speziellen Relations nicht angezeigt werden?
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    deine Begrifflichkeiten sind mir iwie bisserl wirr.
    Datenbänker belieben gelegentlich, auch Tabellen als Relationen zu bezeichnen, wovon ich garnix halte.
    Bei mir sind DataTables Tabellen, und DataRelations sind Relationen.
    Und dann kann man nur Tabellen aus dem Datenfenster ziehen.

    vlt. erläuterst du noch genauer, was du für Tabellen angelegt hast: Buchungen gibts, und was noch? Konten?
    Also da könnte ich mir ein Modell wie folgt vorstellen:

    Konto->Buchung, wäre zB eine sinnvolle 1:n - Relation

    Warum du deine Tabellen nicht im Datenfenster angugge kannst, weißichnich - solltest du allerdings, jdfs. wenn sone Tabelle im Dataset vorhanden ist.
    Vielleicht VS schließen und wieder öffnen.

    ErfinderDesRades schrieb:

    deine Begrifflichkeiten sind mir iwie bisserl wirr.

    Na da solltest du erstmal mein DataSet sehen :D . Habs mal als Anhang beigefügt.

    Also, der Newbie verucht nochmal zu erklären, was ihn drückt:
    Wichtiger Hinweis: Mein Prog wird kein Kassenbuch und ist nicht zur Verarbeitung realer Finanzvorgänge gedacht. Es soll dazu dienen, meine Einnahmen und Ausgaben zu planen. Ich gebe also alles ein, was ich so bezahlen muss und was ich einnehme. Monatliche Ausgaben, jährliche Ausgaben, einmalige Ausgaben, mein kümmerliches Gehalt... und wenn ich dem Prog sage: wie siehts denn zB im Februar 2012 aus, dann soll es mir Einnahmen und Ausgaben auflisten und unten ausrechnen, was übrig bleibt.

    In der DataTable Buchung, da sind die Daten drin, um die es im wesentlichen geht. Diese Buchungen haben Properties, die ich den Benutzer nicht per Hand in Textboxen schreiben lasse, sondern er soll sie aus Combos aussuchen. Die Combos werden über DataTables gefüllt, die per DataSet mit den Buchungen verbunden sind. Alsda wären: Buchungsart (Einnahme oder Ausgabe), Konto, Kategorie, Zahlungsart (Überweisung, Dauerauftrag, Abhebung etc.), Fälligkeit (einmalige Buchung, monatlich, jährlich etc.pp) und alles sowas. BTW: ein paar Properties darf der User auch selbst eintragen: den Namen der Buchung, Beginn, Ende, Betrag, Bemerkungen. Bin ich nicht nett?

    Na jedenfalls: Das alles klappt supi. Ich habe eine Form für meine Buchungen, in der neben ein paar Textfeldern auch ein Haufen Combos sind, von wegen Auswahllisten. Habe ich mit ein bisschen Fummeln hinbekommen (habe schon Einiges von dir gelesen, danke für deine Tuts!).

    Aber nu? Mein Programm soll aber folgendes können: ist ja schön, dass eine Buchung normalerweise einen bestimmten Betrag hat. Aber bei wiederkehrenden (zB monatlichen) Buchungen solls die Möglichkeit geben, bei Bedarf von diesem (Standard-)betrag abzuweichen. Und zwar in zwei Richtungen. Standardabweichungen meint, dass du für bestimmte Monate (in jedem Jahr) der Buchung andere Beträge zuweisen kannst. Zu Weihnachten brauchste halt mehr Geld für Essen. Gänse kosten nunmal und dann auch noch der ganze Spekulatius. Weiterhin kann ja auch immer mal was passieren, weswegen man einmalig vom Standardbetrag abweichen will. Beispiel: ich plane normalerweise monatlich eine bestimmte Summe für ein Hobby ein. Meinetwegen Modelleisenbahn. Im Monat X ist aber eine fette Ausgabe in Sicht (Autowartung oder Frauchen braucht neue Kleider, was weiß ich). Also muss ich wohl in diesem Monat ein bisschen weniger fürs Hobby einplanen. Eine einmalige Abweichung vom normalen Betrag für diesen Posten.

    Daher habe ich zwei Tabellen: Standardabweichung für die Weihnachtsgans und Einmalabweichung, wenn mein Hobby unter Frauchens Kleidern leidet. Ist über die id mit DataTable Buchung im DataSet verknüpft und ich kann für einen Zeitpunkt X einen anderen Betrag für meine Buchung definieren. Wenn ich dann in einem Report meine Buchungen auswerte, muss die Programmlogik also prüfen, ob für eine Buchung eine Abweichung vorliegt oder der Standardbetrag genommen werden soll, damit sie im Bericht für Monat X auch ja den richtigen Betrag für diese Buchung veranschlagt. So jedenfalls in der Theorie.

    Habe ich mir also ein DataSet gebastelt. Alle Tabellen der Datenbank drinne. Alle mit Relationen verbandeld. Und irgendwo klemmt es jetzt in diesen Relationen (meiner Meinung nach). Die Relationen, wo Buchung auf der :n-Seite der Relation ist (bei Verknüpfung mit Kategorie, Konto, Fälligkeit etc.) funktioniert tadellos. Da, wo Buchung die 1:-Seite ist (Standardabweichung, Einmalabweichung) ist die Relation in den Datenquellen überhaupt nicht präsent. Ich wollte mir DataGridViews in meine Form einbauen (in ein Tabcontrol), die diese Abweichungstabellen anzeigen. Ich dachte, dafür ziehe ich auf meine Form nicht die DataTable zu Einmalabweichung bzw. Standardabweichung, sondern die Relation zwischen ihr und der Buchungen-Tabelle. Aber das geht nicht. Ich habe Relationen zwischen Tabelle Buchung und diesen Abweichungstabellen, die werden aber im DataSet in den Datenquellen einfach nicht angezeigt und somit offenbar von VS überhaupt nicht wahrgenommen. Normalerweise sehe ich doch im Baum der übergeordneten Tabelle einen Knoten, der auf die Relation zur untergeordneten Tabelle verweist. Hier nicht. Siehe zweiten Anhang. Aber wer weiß, vielleicht habe ich ja auch total verknotet gedacht. Oder ist mein Tabellendesign total verschrottet???
    Bilder
    • Unbenannt.PNG

      89,64 kB, 1.209×568, 205 mal angesehen
    • Datenquellen.PNG

      21,35 kB, 303×596, 203 mal angesehen
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

    Marsianer schrieb:

    Normalerweise sehe ich doch im Baum der übergeordneten Tabelle einen Knoten, der auf die Relation zur untergeordneten Tabelle verweist. Hier nicht.

    Hmm. Keine Ahnung. Sieht alles total richtig aus, und warum die EinmalAbweichung nicht als Unterknoten von Buchung auftaucht ist mir auch unerfindlich.

    Wie gesagt: Alle Fenster explizit Schließen, VS beenden und wieder öffnen - vlt. kapierters dann.
    Und KOmpilieren, mit strg-shift-B

    ErfinderDesRades schrieb:

    Wie gesagt: Alle Fenster explizit Schließen, VS beenden und wieder öffnen - vlt. kapierters dann.
    Und KOmpilieren, mit strg-shift-B

    Hat leider nix genutzt :( . Na dann werde ich wohl die CRUD's für die Abweichungstabellen und die Synchronisation mit dem Buchungsdatensatz zu Fuß über die Ereignisse machen müssen. Vielleicht hat ja die Expressversion von VB so ne geheime Routine, die einen zu sowas zwingt, um den Lerneffekt zu optimieren :rolleyes:
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    probier eher, eine neue Tabelle anzulegen, ob die dann geht. Das ist eiglich eine zuverlässige Technik, da sollte man sich keine Workarounds für angewöhnen.

    Oder zipp mal die ganze solution (ohne DB) und hängs an, dann kannichdajamal reingugge.

    ah - als zipper für so uploads und Backups kannich SolutionExplorer anbieten
    Hallo,

    ich habe mal parallel im msdn-Forum angefragt und da hat jemand von Microsoft geantwortet, dass mein Tabellendesign nicht funktionieren kann, weil die Bindungen in unterschiedliche Richtungen gehen. Leider hat er net gesagt, wie man das Problem umgehen kann. Kann doch nicht sein, dass ich der Einzige bin, der sowas konstruiert hat. Vermutlich kommt das doch alle Nase lang vor, dass eine Tabelle sowohl untergeordnete als auch übergeordnete Beziehungen hat.

    Oder nicht?

    Ich hänge mal die Solution als Zip ran
    Dateien
    • Buchhalter.rar

      (731,74 kB, 131 mal heruntergeladen, zuletzt: )
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    eben mal "Sowohl Beziehungs als auch Frendschlüsseleinschränkung" aktiviert - fertig

    (kann natürlich sein, dass diese Konfiguration nicht auf deine Anforderungen passt, aber die blicke ich nicht ganz durch)

    Und MS - Mitarbeiter erzählen so ein komisches Zeug?

    Oder der bezog sich auf was anneres.

    ErfinderDesRades schrieb:

    eben mal "Sowohl Beziehungs als auch Frendschlüsseleinschränkung" aktiviert - fertig

    Arrrglh!

    Dankeschön. Das Problem ist meinem Geringwissen geschuldet. Zu meiner Ehrenrettung muss ich aber sagen, dass ich den Relationseinschränkungen schon hinterhergegoogelt habe, aber selbst auf msdn wird das nicht gerade allgemeinverständlich erklärt. Fremdschlüsseleinschränkung ist mir ja noch einigermaßen klar, das sind die update- und delete-Weitergaben an die untergeordnete Tabelle, Was aber ist eine Beziehungsbeschränkung? Oder binnich nur zu blöd zum suchen? Im msdn habe ich eigentlich genau die gleiche Frage gestellt wie hier, einschließlich der gleichen Bildanhänge. Wurscht.

    So, habs bei mir jedenfalls auch umgestellt und siehe... es ward Licht. Die Nodes sind daaaaa! :P :P :P
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

    Daten im Datagridview werden nicht persistiert

    Muss leider nochmal nachhaken:

    Habe die untergeordneten "Abweichungs"-Tabellen als DGV's über die Nodes in den Datenquellen in meine Form gezogen. Bisschen formatiert... schön.

    Ich kann da jetzt auch Daten erfassen. Wenn ich dann zwischen den Datensätzen blätter, dann zeigt mir mein Prog diese Detaildaten in den DGV's auch immer brav an.
    Jetzt kommts: wenn ich die Form zumache und wieder öffne, sind die DGV's leer.
    Heißt für mich: im DataSet warense drin, aber sie wurden nicht in die DB übertragen. Ich habe den Speichenbutton meines BindingNavigators gedrückt, Ehrenwort!

    Ich dachte, dass TableAdapterManager.UpdateAll() das alles für mich erledigt. Ist offenbar nicht der Fall. Nu bin ich etwas ratlos. Liegts an den Restriktionen, die ich in den Relations zwischen Buchungstable und den Abweichungstables eingestellt habe, damit die in den Datenquellen sichtbar werden (sowohl Beziehungs- als auch Fremdschlüsseleinschränkungen)? Oder macht der TAM das einfach net und ich muss beim Save-Event per Hand nachhelfen (aber wie???)
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Ja, den Code erstellt VB automatisch mit dem Navigator und die anderen Daten in der Form werden auch brav abgespeichert. Nur halt die DGV's ignoriert er.

    Ach sch... bevor ich da weiter rumpfriemel schau ich mir doch erstma deine objektorientierte Lösung an... :thumbup:
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Nee, sind sie nicht. Das war übrigens der Auslöser, mit dem ich mir den TableAdapterManager geschreddert habe (habe ja darüber in einem anderen Thread gejammert): Ich hatte da den TableAdapter meiner "Abweichungs"-Tabelle eingetragen, in der Hoffnung, dass er die dann bei UpdateAll() ebenfalls persistiert. Führte aber dazu, dass er überhaupt keine Daten mehr geladen hat, selbst nachdem ich die Änderung im Manager rückgängig gemacht hatte. Ist also offenbar ein probates Mittel, ihn zu shreddern :D .

    Deswegen steht im TableAdapterManager jetzt nur noch der TableAdapter meines eigentlichen BuchungsDataSets... und er speichert mir immer noch nicht die neuen Daten aus dem DataGridView ab.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

    Marsianer schrieb:

    und er speichert mir immer noch nicht die neuen Daten aus dem DataGridView ab.

    überhaupt keine?

    weil dass er den aktuell in Bearbeitung befindlichen DS nicht abspeichert ist absicht. Eine Bearbeitung muß abgeschlossen sein, dass sie übernommen wird.
    Dazu ruft man am besten Form.Validate() auf, das schließt offene Bearbeitungen und validiert alle Eingaben .

    (Aber wenndedich inzwischen mittm Ersatzmonster beschäftigst - da ist das mit drin.)
    Leider nicht. Ich kann wunderbar das DataSet mit neuen und geänderten Daten füttern... solange ich die Form nicht verlasse, ist alles schön da. Aber wenn ich die Form schließe und wieder öffne... sind meine normalen Daten alle wieder da, nur die DGV's sind leer.
    Die DateGridViews stecken in einem TabControlContainer auf unterschiedlichen TabSides (sonst fressen sie zuviel Platz), aber das kann doch nix mit dem Speichern zu tun haben, oder???

    Mein SpeicherCode sieht bisher folgendermaßen aus:

    VB.NET-Quellcode

    1. ' Wird bei Saveereignis ausgeführt.
    2. ' Eingaben validieren
    3. ' Änderungen committen
    4. ' Update gegen DB fahren
    5. Me.Validate()
    6. Me.EinmalabweichungBindingSource.EndEdit()
    7. Me.StandardabweichungBindingSource.EndEdit()
    8. Me.BuchungBindingSource.EndEdit()
    9. Me.TableAdapterManager.UpdateAll(Me.BuchhalterDataSet)


    Ich hatte schon über msdn rausgefunden, dass der automatisch generierte Code nur die erste Bindingsource endedit und dass man das für die übrigen zu Fuß nachproggen muss. Hab ich auch gemacht. Aber Ergebnis: is null. Falls jetzt nich noch ganz kurzfristig jemandem was einfällt, muss dein Monster ran. Habe sogar einen Code von msdn ausprobiert, bei dem man die einzelnen DataTables per Hand und in einer bestimmten Reihenfolge updatet. Hat mir gleich erstma meine Anwendung geschreddert :wacko: . Ein Hoch aufs Backuppen.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Versuch mal 'rauszukriegen, ob der TableAdapterManager überhaupt Updates annimmt, nach dem Muster:

    VB.NET-Quellcode

    1. Dim n = Me.TableAdapterManager.UpdateAll(Me.BuchhalterDataSet)
    .
    Das könntest Du auch für die einzelnen TableAdapter ausprobieren, und so ein bischen mehr Information bekommen.