Dataset die n'te

  • VB.NET

Es gibt 53 Antworten in diesem Thema. Der letzte Beitrag () ist von Storch.

    Dataset die n'te

    Hi Leutz,

    ich stehe mit Dataset's immer noch auf Kriegsfuß. Da aber kein Weg dran vorbei führt, allgemein und für mich auch nicht, will ich hier nach und nach ein paar Fragen loswerden.
    Dabei handelt es sich erstmal eher um Grundsätzliches.

    Thema: Wie bzw. wo speichert ein Dataset seine Daten???

    Bisher war ich der Annahme, das Daten eines Datasets exportiert werden müssen z.B. mit WriteXML (schon selbst angewendet).
    Nun habe ich mir heute ein Dataset erstellt, ein DGV an eine der Tabellen gebunden und dort mal versucht, was einzutragen. Das schlug zwar fehl, aber Versuch macht kluch.

    Kurios finde ich nun folgendes: Ich habe noch nirgends einen Export vorgesehen. Als ich nun den Primärschlüssel der entsprechenden Tabelle ändern wollte ging das nicht, weil dort angeblich schon Daten drinne sind.

    1. Wo sind die gespeichert u./o. kann ich diese Daten sehen???
    2. Hat er automatisch irgendwo in ein File exportiert??? .... Welches ich dann aber nicht finde(bisher)
    3. Bedarf es überhaupt des Exportes??? ... Ich hab das Projekt geschlossen und neu gestartet. Es waren immer noch Daten vorhanden.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Hhmmm ich hab nu die Tabelle fix neu gemacht. Aber wenn Dich das prinzipiell interessiert, will ich heute Abend versuchen, die Nummer nochmal zu reproduzieren.

    Unterdessen hab ich alles korrekt eingestellt(Datentypen, Excrement etc.), Read und WriteXML eingebaut und das läuft mit einer Tabelle prima. Da ich aber ein Datenmodell mit 5 Tabellen handlen muss, werde ich sicher noch die eine oder andere Frage haben. Hauptsache mir pfeifft das XML-File nicht wieder mal ab, wenn ich am experimentieren bin.

    Also wenn ich das Problem nochmal nach bilden soll, dann sag.... hab aber eben erst Abends wieder Zeit.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Ich konstruiere ein Form frm_emails zum versenden von EMails.

    In frm_emails. HIer wird in Form_Load WriteXML ausgeführt, wodurch das Dataset mit den Daten aufgefüllt sein müsste/muss.

    Zur Auswahl der Empfänger verwende ich 2 Buttons (To u. BCC)
    Mit beiden öffne ich ein Form frm_empfängerauswahl. Hierin ein DGV zur Darstellung der Daten, an die richtige Tabelle gebunden.

    Rufe ich dieses Form per Buttonclick aber auf, erscheinen dort in dem DGV erstmal keine Daten. Dies klappt erst, wenn ich dort ebenfalls WriteXML ausführe.

    Frage:
    Ist das normal? Wie verhält sich das?

    Ich dachte, wenn das Dataset per WriteXML einmal aufgefüllt ist, kann ich danach überall mit den Daten arbeiten.
    Oder muss WriteXML wirklich für jedes Form ausgeführt werden?
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Wie ich das Projekt aus dem "FourView"-Thread verstehe, wird das Objekt deiner DataSet-Klasse in jeder Form angelegt. Und wenn du das Objekt in dieser Form mit Daten füllst (wie auch immer), dann hat das andere Objekt (in der anderen Form) davon nichts mitgekriegt... Denn es sind unterschiedliche Objekte mit unterschiedlichen Daten, das "DataSet", was du angelegt hast, ist eine Klasse (der Bauplan).

    Wenn du also das selbe DataSet-Objekt in einer anderen Form haben willst, musst du es übergeben (oder shared machen).

    Ich hoffe, ich habe es jetzt richtig verstanden.
    Ha... das macht Sinn.

    Bei Deinen Worten ist mir eingefallen, dass, wenn ich in einem leeren Form irgendeine Datenbindung vornehme, der Designer neben der BindingSource auch immer ein DatSet-Object einfügt.

    Daher hast Du Recht und das Verhalten ist richtig. :)
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Hallo,
    es gibt eine bedenkenswerte Alternative zu Datasets, wenn es hauptsächlich darum geht, Daten im Grid anzuzeigen: die BindingList.
    codeproject.com/Articles/23222/BindingList-Example
    Statt einem Dataset wird eine selbst erstellte Klasse ans DataViewGrid gebunden.
    Der Overhead ist bedeutend geringer, hat Vor- und Nachteile.
    @coldfire

    danke für den Hinweis, aber ich hab grade angefangen, bei den Datasets einigermaßen durch zu sehen, da tu ich mir, zumindest im Moment, nicht noch wieder was neues an.
    Aber ich hab ne Liste, wo ich mir solche Hinweise notiere. :)

    @vb1963
    DU hast völlig recht. Ich habs lediglich in Gedanken durcheinander gebracht. Richtig wäre REadXML bei Form_load
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Dein Problem ist das Problem formübergreifenden Databindings.
    Da der Form-Designer im Form ein typDataset generiert, kriegt man leicht nicht mit, dass, wenn man 2 Forms offen hat, dass dann auch 2 Datasetse in der Anwendung rumfahren, und das ist eine architektonische Katastrophe, denn das eine Dataset weiß ja nix vonne Änderungen im anneren Dataset, und wenn in beiden geändert wurde, was soll man nu abspeichern? - also die ganz ganz klassische Redundanz-Problematik, aber volles Programm.
    Die Lösung ist nicht ganz trivial: Ich stöpsel zur Laufzeit alle gleichartigen Datasetse um auf ein einziges. Dann wirkt jede Änderung gleichzeitig in jedem Form, und es ist auch egal, von welchem Form aus abgespeichert wird - es ist ja doch ein und dasselbe Dataset.
    Die Umstöpselei - na, das könnte dir sogar liegen - du hast dich doch gewaltig in Reflection eingearbeitet - und - ja, ich nämlich auch :D

    gugge Viele DbSamples, die Variante mit der Helpers-Dll.

    Ach, das Film-Sample ist noch primitiv: der häufigste Fall: Editieren eines einzelnen Datensatzes im DetailView.
    In den Helpers ist auch die Extension-Method Dataset.Register(Form), mit der man wirklich 2 komplett unterschiedliche Views in 2 ansonsten unabhängigen Forms erstellen kann, und Änderungen im einen Form rückwirken ins annere hinein.
    JO, dass is wohl so, wie wen ich mir 10 Zeitungen kauf, je eine fürs Klo. Küche, schlafzimmer, wohnzimmer, auto arbeitsplatz etc.
    Anstatt mir die eine Zeitung untern Arm zu klemmen.

    Deswegen war ich ja so verwirrt, weil es ja logisch is , das Redundanzen entstehen, wenn ein Dataset mehrfach geladen wird.
    Ich versteh da nicht wirklich, warum MS sowas macht.

    Schon in einem einzigen Form frage ich mich: Wieso baut er das Dataset jetzt noch in dieses Form ein? Es existiert doch schon.
    Wieso greifen die BindingSources nicht direkt auf das zentrale/globale Dataset zu?

    Aber ich sehe schon, das das ein erschöpfendes Thema für mich wird.. meine ... wenn ich damit fertig bin, dann bin ich erschöpft.

    Ich werde mir Deine Hinweise mal zu Gemüte führen.... vor der Erschöpfung.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!

    Storch schrieb:

    Schon in einem einzigen Form frage ich mich: Wieso baut er das Dataset jetzt noch in dieses Form ein? Es existiert doch schon.
    Wieso greifen die BindingSources nicht direkt auf das zentrale/globale Dataset zu?

    Wo existiert das OBJEKT schon?
    Wo ist das zentrale OBJEKT Dataset? Es ist nur eine Klasse...
    Ja guck, die SOnne geht auf. Wieso bist Du hier und nicht im Wochenende???

    Jaaaa, du hast recht. Es ist natürlich NUR eine Klasse. Sorry aber ich kann das alles halt noch nicht so präzise erfassen.

    Ich hab wohl irgendwie gedacht, wenn so ein Dataset einmal instanziert wurde, wäre es öffentlich zugänglich. Aber das sind andere Objekte ja auch nicht , jedenfalls nicht ohne extra Maßnahmen.

    Hab ich auch @Erfinders Beispiele angesehen. Sind interessante Sachen. Zudem glaub ich jetzt kapier zu haben, wozu der Namespace gut ist bzw, wie man ihn nutzen kann. :)
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!

    sonne75 schrieb:

    Du kannst es öffentlich zugänglich machen, wenn du es willst. Aber solange du es in einer Klasse (Form ist auch nur eine Klasse) deklariert hast, dann ist es nur in der Klasse da...


    Ist klar, ich weiss auch nicht, was mir da im Kopf rumlief.

    sonne75 schrieb:

    Ich habe auch zu Hause Internet. :D

    Das hätte ich jetzt garnicht vermutet :rolleyes: ;)
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Moin,

    ich werd aus der Hilfe nicht schlau.

    Ist eine BindungSource nun 0 -oder 1-Basiert????

    Ich würde NUll vermuten

    Edith: Hat sich erledigt, hab's nun endlich gefunden. Sie ist 0-basiert
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!

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

    Gültigkeitsprüfung... auf welcher Ebene

    Hossa Leutz,

    ich hab da mal folgenden Code:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub dgv_adresses_RowValidating(sender As Object, e As DataGridViewCellCancelEventArgs) Handles dgv_adresses.RowValidating
    2. Dim bInvaliMail As Boolean
    3. Dim currRow = DirectCast(DirectCast(Me.TblmailadressesBindingSource.Current, DataRowView).Row, email_daten.tbl_mailadressesRow)
    4. Dim regex As New cls_RegexUtilities
    5. If Not currRow.mad_mailadress Is Nothing Then
    6. 'Email auf Gültigkeit prüfen
    7. If Not regex.IsValidEmail(currRow.mad_mailadress) Then
    8. bInvaliMail = True
    9. End If
    10. Else
    11. bInvaliMail = True
    12. End If
    13. regex = Nothing
    14. If bInvaliMail Then
    15. e.Cancel = True
    16. MessageBox.Show("Die Mailadresse fehlt oder sie ist ungültig!" & Environment.NewLine & _
    17. "Geben Sie eine gültige Mailadresse ein!", "Aktion nicht möglich!", _
    18. MessageBoxButtons.OK, MessageBoxIcon.Warning)
    19. dgv_adresses.CurrentCell.Selected = False
    20. dgv_adresses.CurrentRow.Cells.Item(3).Selected = True
    21. End If
    22. End Sub


    Ich nutze das DGV-Event RowValidating um eine Gültigkeitsprüfung auszulösen. Die Prüfung selbst erfolgt, sozusagen, auf BindingSource-Ebene. Wird die Prüfung nicht bestanden, nutze ich die Cancel-Methode, um die Eingabe abzubrechen.

    Nun wurde mir in einer privaten Diskussion nahegelegt, die Prüfung sogar auf Tabellenebene zu verlegen. Ich sehe die Notwendigkeit dafür nur bedingt. In meinem Fall ist es so, dass ich die Gültigkeitsprüfung nur ein einziges mal innerhalb meiner Anwendung benötige und finde meine Variante daher ausreichend. Wenn natürlich Funktionen programmiert werden, die mehrfach zur Verfügung stehen sollen, kann ich die Anregung verstehen.

    Meine Frage ist nun, wie es denn aussehen kann, diese Prüfung auf Tabellenebene zu vollziehen. Es gibt die Table-Events RowChanged und RowChanging, die man dafür wohl nutzen kann.
    Mir ist nur unklar, wie ich diese Events nutzen kann. Nach meinen Recherchen ist es wohl nicht möglich, wie zb bei Controls über die Eigenschaften ein Event einzubinden. Daher nehme ich an, das dafür ein Delegat erstellt werden muss (wenn das denn auch so heißt). Wie und wo kann man das machen. Ein Beispiel wäre schön.

    Zudem würden mich natürlich Meinungen interessieren, welcher Weg nun am Geeignetsten ist.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Wenn das halt tut, wasses soll, und du sonst nicht so viel zu validieren hast, ist das doch ok. Nur kannman den Code noch sehr vereinfachen:

    VB.NET-Quellcode

    1. Private Sub dgv_adresses_RowValidating(sender As Object, e As DataGridViewCellCancelEventArgs) Handles dgv_adresses.RowValidating
    2. if currRow.mad_mailadress is Nothing oerelse not RegexUtilities.IsValidEmail(currRow.mad_mailadress) Then
    3. e.Cancel = True
    4. MessageBox.Show("Die Mailadresse fehlt oder sie ist ungültig!" & Environment.NewLine & _
    5. "Geben Sie eine gültige Mailadresse ein!", "Aktion nicht möglich!", _
    6. MessageBoxButtons.OK, MessageBoxIcon.Warning)
    7. dgv_adresses.CurrentCell.Selected = False
    8. dgv_adresses.CurrentRow.Cells(3).Selected = True
    9. End If
    10. End Sub
    Beachte, dassich RegexUtilities.IsValidEmail(text) als Public Shared Function angenommen habe.
    Weil die Validitäts-Prüfung einer Email-Addresse keine objekt-gebundene Aufgabe ist, braucht man dafür auch nicht jedesmal ein Objekt zu erstellen.

    Ansonsten, wennde dich in Datenvalidierung einarbeiten willst, gugge vlt. IDataErrorInfo.

    Also ist schon toll, was dafür an Infrastruktur bereitsteht. Aber mir gehts tatsächlich eher wie dir: Meist hab ich garnet soo gewaltig viel zu validieren, also beschleicht mich etwas das Gefühl, dass da wieder die Architektur-Astronauten vom Boden abheben ;)
    Also liege ich in meinem Denken ja gar nicht so falsch.

    Ich muss mich aber wohl mal mit OrElse etc vertraut machen. Aus VBA kenne ich es nicht und bisher hab ich es eher ignoriert.
    RegexUtilities.IsValidEmail ist noch nicht Shared. Wenn ich das abänder dann bemault mir der Compiler eine Variable.
    Habs bisher noch nicht so wirklich geschnallt, wie das zusammenhängt aber ich komm da sicher auch noch dahinter
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!

    VB.NET-Quellcode

    1. Dim currRow = DirectCast(DirectCast(Me.TblmailadressesBindingSource.Current, DataRowView).Row, email_daten.tbl_mailadressesRow)


    Moinsens.

    Mir spuckt die Idee im Kopf rum, dass man obiges Doppel-Casting (wenn es sich schon nicht vermeiden lässt), vielleicht in die BindingSource-Klasse einbinden kann.

    Leider bin ich mir nicht im klaren, wie das vonstatten gehen kann und ob das überhaupt machbar und sinnvoll ist.

    Würde mich interessieren, was die Experten dazu sagen
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!