DataSet Datenbindung an GridView



  • Hallo Leute,

    ich habe folgendes Problem. Ich möchte gerne zwei Tabellen über ein ein DataSet verbinden und dieses DataSet an ein dataGridView binden. Ich habe bisher nur Code für c# gefunden, aber bei der Umsetzung gibt es Probleme.

    In der ParentTabelle soll eine ID stehen und zur dieser ID soll es ein ChildTabelle geben wo weitere Daten enthalten sind

    Code:

    dsDataset = gcnew DataSet("Dataset");
    dtparentDaten = gcnew DataTable("parentDaten");
    dtchildDaten = gcnew DataTable("childDaten"); 
    dsDataset->Tables->Add(dtparentDaten);
    dsDataset->Tables->Add(dtchildDaten);
    // Tabellen mit Werten füllen //
    

    Relation

    DataColumn^ parentColumn = dsDataset->Tables["parentDaten"]->Columns["ID"];
    		DataColumn^ childColumn = dsDataset->Tables["childDaten"]->Columns["Wert"];
    		DataRelation^ relation = gcnew DataRelation("parentChild", parentColumn, childColumn);
    //dsDataset->Tables["childDaten"]->ParentRelations->Add(relation); 
    //gibt Fehlermeldung wenn nicht die Zeilen der Parenttabelle mit den Anzahl der Zeilen von der zweiten Tabelle übereinstimmen.
    

    Der Code aus c# umgesetzt in c++/cli läuft nicht:

    datagridview1.SetDataBinding(dsDataset, "parentDaten");
    

    Wie setzte ich diesen Code in C++/cli um, da es in c++ kein SetDataBinding für Datagridview gibt?
    [EDIT]

    //Erstellen eines DataGridObjektes
    DataGrid^ dataGrid1 = gcnew DataGrid();
    dataGrid1->SetDataBinding(dsDataset, "parentDaten");
    //Bindung
    dataGridView1->DataSource = dataGrid1;
    

    Aber es wird nichts angezeigt, warum keine Ahnung?

    Frage 2, wie lege ich ein PrimaryKey in c++/cli für eine Spalte fest?

    MfG
    Hotte



  • Versuche mal

    datagridview1->DataSource = dsDataset->Tables["parentDaten"];
    


  • Danke das hab ich auch schon hinbekommen. Doch mein DataRelation funktioniert überhaupt nicht.

    DataColumn^ parentColumn = dsDataset->Tables["parentDaten"]->Columns["ID"];
    DataColumn^ childColumn = dsDataset->Tables["childDaten"]->Columns["Wert"];
    DataRelation^ relation = gcnew DataRelation("parentChild", parentColumn, childColumn);
    dsDataset->Tables["childDaten"]->ParentRelations->Add(relation);
    

    Fehlermeldung: Diese Einschränkung kann nicht aktiviert werden, da nicht alle Werte entsprechende übergeordnete Werte besitzen.

    Als Beispiel möchte ich haben:
    In Tabelle 1 parent steht eine ID-> 10;
    In der Tabelle 2 child werden alle passenden Einträge für die ID-> 10 angezeigt.
    Wie sieht denn dafür die Syntax aus?

    Für das DataGridview

    datagridview1->DataSource = dsDataset->Tables["parentDaten"];
    datagridview1->DataMember = "parentDaten->relation";
    


  • Ich weiß gar nicht wie du zwei Tabellen in einem Datagridview anzeigen kannst. Geht sowas überhaupt? Ich würde:
    * zwei Datagridviews und zwei BindingSources nehmen
    * BindingSource bndParent bekommt als DataSource das Dataset und als Datamember "parentDaten"
    * Grid grdParent bekommt als Datasource bndParent
    * BindingSource bndChildren bekommt als DataSource das bndParent und als Datamember das Relation-Objekt zwischen beiden Tabellen (über Name referenzieren)
    * Grid grdChildren bekommt als Datasource bndChildren



  • Sorry für die etwas missverständliche Ausdrucksweise. Wie du schon sagst, möchte ich zwei DataGridView haben. In einem sind die ParentID und wenn ich auf einen ParentId auswähle, soll im zweiten DataGridView die Childeigenschaften angezeigt werden.

    [Edit]
    Hab es soweit hinbekommen, dass die Relation angezigt wird, nur wenn ich jetzt einen anderen Datensatz auswählen möchte passiert rein gar nichts. Hier noch mal die Beziehung:

    DataColumn^ parentColumn = dsDataset->Tables["parentDaten"]->Columns["ID"];
    DataColumn^ childColumn = dsDataset->Tables["childDaten"]->Columns["ID"];
    DataRelation^ relation = gcnew DataRelation("parentChild", parentColumn, childColumn);
    dsDataset->Tables["childDaten"]->ParentRelations->Add(relation);
    

    Beziehung gebunden

    BindingSource^ bndParent = gcnew BindingSource;
    BindingSource^ bndChild = gcnew BindingSource;
    
    bndParent->DataSource = dsDataset;
    bndParent->DataMember = "parentDaten";
    bndChild->DataSource = dsDataset->Tables["parentDaten"];
    bndChild->DataMember = "parentChild";
    
    dataGridView2->DataSource = bndParent;
    dataGridView1->DataSource = bndChild;
    

    MfG
    Hotte



  • Habs hinbekommen:

    Fehler lag in der Bindung. KorrekterCode:

    bndChild->DataSource = bndparent;
    

    Dankeschön nochmal an witte für die Hilfe 👍 👍

    MfG
    Hotte



  • Ich bin es nochmal!
    Folgendes weitres Problem. 😞 Ich möchte nun aus der ParentTabelle einen Eintrag löschen und dieser soll auch in der ChildTabelle mit geändert werden. Hab zwar Code für C# gefunden und bei msdn aber kann es nicht auf C++/cli projektieren.
    Code:

    // Löschen einiger Lieferanten 
        ForeignKeyConstraint fkey = 
         (ForeignKeyConstraint)ds.Tables["Produkte"].Constraints[0]; 
        fkey.DeleteRule = Rule.SetNull; //Rule in C++ keine Ahnung?!
        for (int i = 0; i < 3; i++) 
          ds.Tables["Lieferanten"].Rows[i].Delete();
    

    gefunden bei
    [url]
    http://openbook.galileocomputing.de/visual_csharp/visual_csharp_28_005.htm#mj7b0943565255695a3b6f41001d982e4e
    [/url]



  • Wenn du ein DataRelation-Objekt mit dazugehörigen Fremdschlüsselbeziehungen zwischen beiden Tabellen hast kannst du dort Aktualisierungs- und Löschweiterleitungsregeln definieren: ON DELETE CASCADE bedeutet, dass wenn ein Masterdatensatz entfernt wird sollen die dazugehörigen Detailsätze ebenfalls gelöscht werden.
    Der von dir gezeigte Code macht es sich unnötig kompliziert: er "erdet" die Detailsätze um sie danach manuell zu löschen. Du kannst die Cascade-Regel setzen dann passiert das automatisch. Vllt sowas wie

    ForeignKeyConstraint^ fkey =
         (ForeignKeyConstraint^)ds->Tables["Produkte"]->Constraints[0];
    fkey->DeleteRule = System::Data::Rule::Cascade;
    

    (Möglicherweise fehlerhaft habe gerade kein C++/CLI-Ado.Net-Projekt da)

    P.S. Du könntest das auch in C# entwickeln wenn du die Option hast. Ist um Einiges einfacher. Eine zweite Möglichkeit besteht darin das DataSet in einem C#-Projekt mal nachzubauen (dort gibt es bequeme Entwurfsassistenten) und sich den vom Designer erzeugten Code mal anzuschauen.



  • Jo Danke! Klappt halbwegs. Ich habe drei Datensätze die ich löschen möchte und immer der zweite Datensatz bleibt erhalten mit der Fehlermmeldung: An der Position zwei befindet sich keine Zeile??

    Problem zwei: Möchte ich jetzt die Relation aufheben

    dsDataset->Tables["childDaten"]->ParentRelations->Remove("parentChild");
    

    und eine Tabelle löschen gibt es auch eine Fehlermeldung 😞

    Und ich muss dies in C++/Cli programmieren, obwohl ich langsam die vorzüge von C# sehe. 😉


Anmelden zum Antworten