Mise à jour d'une base de données à partir d'un DataGridView

MGD Software Messages postés 188 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 4 juillet 2024 - Modifié le 22 août 2019 à 15:50
MGD Software Messages postés 188 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 4 juillet 2024 - 22 août 2019 à 21:20
Bonjour,

J'ai un problème avec un DataGridView lorsque je tente de mettre à jour la table sous-jacente avec une insertion (et sûrement avec une suppression, mais je n'en suis pas encore là). Pourtant tout va bien lorsque l'on met à jour une ligne existante.

J'ai bien trouvé des tonnes d'explications sur le DataAdapter, les commandes d'insertion, et de suppression. Cependant, le DataGridView charge une table de façon générique, et donc les champs ne sont pas connus à l'avance. Je ne sais donc pas trop comment faire pour générer les commandes d'insertion et de suppression. Il y a sûrement un moyen de faire autrement que l'usine à gaz que je m'apprête à faire.

Voici le code de chargement du DataGridView (ODA est un OleDbDataAdapter déclaré au niveau classe) :

string Sql = "SELECT * FROM [" + tbrTableList.Text + "]";
ODA = new OleDbDataAdapter(Sql, Common.gCnx);
DataSet DS = new DataSet();
ODA.Fill(DS);
DS.Tables[0].TableName = tbrTableList.Text;
DataGrid.DataSource = DS.Tables[0];
sbrTableName.Text = tbrTableList.Text;


Et voici la routine de traitement des modifications

private bool TraiteModifs()
{
    DataTable DT = DataGrid.DataSource as DataTable;
    if (DT != null && ODA != null && DT.DataSet != null)
    {
        if (DT.DataSet.HasChanges())
        {
            if (mnuOptionsConfirm.Checked)
            {
                string Prompt = "Des modifications ont été faites à la table courante.\nVoulez-vous les conserver ?";
                DialogResult R = MessageBox.Show(Prompt, sbrTableName.Text, MessageBoxButtons.YesNoCancel);
                if (R == DialogResult.Cancel)
                {
                    tbrTableList.Text = sbrTableName.Text;  // On conserve la même table si changement en cours
                    return false;
                }
                else if (R == DialogResult.Yes)
                {
                    DataTable Changes = DT.DataSet.GetChanges().Tables[0];
                    foreach (DataRow Row in Changes.Rows)
                        for (int i = 0; i < Changes.Columns.Count; i++)
                            Console.WriteLine("{0} = {1}", Changes.Columns[i].ColumnName, Row[i].ToString());

                    OleDbCommandBuilder CmdBld = new OleDbCommandBuilder(ODA);
                    ODA.Update(DT.DataSet);
                    CmdBld.Dispose();
                }
                // else : Pas de modif, mais on ne fait rien et on retourne true pour poursuivre normalement
            }
        }
    }
    return true;
}


Lors d'une mise à jour d'une ligne existante, pas de problème : si on accepte la modif, la base est bien modifiée. Pourtant il n'y a pas eu de définition de la propriété UpdateCommand de ODA ???

Par contre, lors d'une insertion, l'appli plante au niveau de la ligne
 ODA.Update(DT.DataSet);
en disant
Impossible pour Update de trouver TableMapping['Table'] ou DataTable 'Table'.'

D'où les interrogations :
- Quelle est la signification de ce message, que je comprends pas bien ?
- Comment générer les commandes d'insertion et de suppression sans connaître à l'avance la structure de la table source du DataGridView ?

Merci pour vos conseils.

PS : il y a petit bug dans la seconde partie du code (pas d'enregistrement si la confirmation n'est pas demandée !) mais il sera bientôt corrigé. Ce ne sera donc pas la peine de me le signaler...

1 réponse

MGD Software Messages postés 188 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 4 juillet 2024 2
Modifié le 22 août 2019 à 21:21
J'ai trouvé !

En fait, le problème n'est pas dans les requêtes de l'adapter : en faisant
CmdBld.GetxxxxCommand().commandText 
(xxxx = Update, Insert Ou Delete), j'obtiens des requêtes SQL correctes.

En fait j'avais aussi maintenant des plantages lors des mises à jour de lignes existantes.

Le problème provient du message d'exception. Après avoir encore écumé le web avec un paquet de mots clés, j'ai fini par trouver la solution sur StackOverflow.

En fait, il semble que le DataAdapter perde ou ne mémorise pas le nom de la table sur lequel la requête est faite. Il faut donc le lui rappeler.


Donc juste avant le ODA.Update(), j'ai ajouté la ligne :
ODA.TableMappings.Add("Table", sbrTableName.Text);

et maintenant les mises à jour se passent sans problème, en tous cas jusqu'à présent pour les lignes existantes, les suppressions et les insertions.

Bon, j'aurais dû encore chercher avant de lancer ma bouteille à la mer. Mais si ce post peut servir à quelqu'un d'autre...
0
Rejoignez-nous