ADO.NET : Consultation, Ajout, Modification et Suppression de Données
Liaison C# - SQL Server
Cet article présente une approche pratique pour interagir avec une base de données SQL Server en utilisant ADO.NET avec C#. L'objectif est de maîtriser les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) sur une base de données via une interface utilisateur.
Les classes principales d'ADO.NET utilisées pour cette démonstration incluent :
SqlConnection: Gère la connexion à la base de données.SqlDataAdapter: Agit comme un pont entre unDataSetet la base de données, permettant de charger des données et d'enregistrer les modifications.SqlCommand: Permet d'exécuter des commandes SQL (SELECT, INSERT, UPDATE, DELETE).DataSet: Une copie en mémoire des données de la base de données, permettant de travailler de manière déconnectée.
Exercice Pratique 1 : Gestion des Enseignants avec DataGrid
Cette première section détaille la création d'une interface utilisateur et l'implémentation des gestionnaires d'événements pour les opérations CRUD sur une table d'enseignants.
Description de l'Interface Utilisateur
L'interface utilisateur proposée permet la gestion des enseignants. Elle inclut généralement des champs de texte pour afficher et éditer les informations, ainsi qu'un contrôle de type DataGrid pour visualiser les données en tableau. Les menus et boutons suivants sont prévus :
Menu "Connexion"
- Connecter : Établit la connexion à la base de données.
- Déconnecter : Ferme la connexion à la base de données.
Menu "Consultation"
- Premier : Affiche le premier enregistrement.
- Précédent : Affiche l'enregistrement précédent.
- Suivant : Affiche l'enregistrement suivant.
- Dernier : Affiche le dernier enregistrement.
Menu "Action"
- Sélectionner : Charge les données dans le
DataSetet les affiche. - Insérer : Ajoute un nouvel enregistrement.
- Mettre à jour : Modifie l'enregistrement courant.
- Supprimer : Supprime l'enregistrement courant.
Implémentation des Gestionnaires d'Événements
La section suivante détaille l'implémentation C# des fonctionnalités décrites ci-dessus. Les variables nécessaires sont déclarées globalement pour être accessibles par toutes les méthodes de l'interface.
Déclarations des Variables Globales
using System.Data;
using System.Data.SqlClient;
static SqlConnection MySqlConn;
static SqlCommand MySelectCmd, MyInsertCmd, MyUpdateCmd, MyDeleteCmd;
static SqlDataAdapter MySqlDataAdapter;
static DataSet MyDataSet;
static DataRow MyWorkRow;
static int NumEnreg, NbEnreg;
static string MyStrConn, MyStrSelect, MyStrInsert, MyStrUpdate, MyStrDelete;
Méthode Connecter
Cette méthode initialise la chaîne de connexion, ouvre la connexion à la base de données et prépare les objets SqlCommand pour les opérations SELECT, INSERT, UPDATE et DELETE. Elle configure également les paramètres pour chaque commande SQL. La chaîne de connexion pointe vers un serveur local ('Localhost') et utilise l'authentification Windows (Integrated Security = SSPI) pour se connecter à la base de données 'SQLNotation'.
private void Connecter(object sender, System.EventArgs e)
{
MyStrConn = "Server = Localhost; Integrated Security = SSPI; Initial Catalog = SQLNotation";
MySqlConn = new SqlConnection(MyStrConn);
MySqlConn.Open();
MyStrSelect = "SELECT CodeEnseignant, Nom, Prenom, DateNaissance FROM Enseignants";
MySelectCmd = new SqlCommand(MyStrSelect, MySqlConn);
MyStrInsert = "INSERT INTO Enseignants " +
"(CodeEnseignant, Nom, Prenom, DateNaissance) " +
"Values (@CodeEnseignant, @Nom, @Prenom, @DateNaiss)";
MyInsertCmd = new SqlCommand(MyStrInsert, MySqlConn);
MyInsertCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyInsertCmd.Parameters.Add("@Nom", SqlDbType.VarChar, 25, "Nom");
MyInsertCmd.Parameters.Add("@Prenom", SqlDbType.VarChar, 15, "Prenom");
MyInsertCmd.Parameters.Add("@DateNaiss", SqlDbType.SmallDateTime, 0, "DateNaissance");
MyStrUpdate = "UPDATE Enseignants SET CodeEnseignant=@CodeEnseignant, " +
"Nom = @Nom, Prenom = @Prenom, DateNaissance = @DateNaiss " +
"Where CodeEnseignant = @CodeEns";
MyUpdateCmd = new SqlCommand(MyStrUpdate, MySqlConn);
MyUpdateCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyUpdateCmd.Parameters.Add("@Nom", SqlDbType.VarChar, 25, "Nom");
MyUpdateCmd.Parameters.Add("@Prenom", SqlDbType.VarChar, 15, "Prenom");
MyUpdateCmd.Parameters.Add("@DateNaiss", SqlDbType.SmallDateTime, 0, "DateNaissance");
SqlParameter WorkParam = MyUpdateCmd.Parameters.Add("@CodeEns", SqlDbType.TinyInt);
WorkParam.SourceColumn = "CodeEnseignant";
WorkParam.SourceVersion = DataRowVersion.Original;
MyStrDelete = "DELETE Enseignants WHERE CodeEnseignant = @CodeEnseignant";
MyDeleteCmd = new SqlCommand(MyStrDelete, MySqlConn);
MyDeleteCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyDataSet = new DataSet();
MySqlDataAdapter = new SqlDataAdapter();
MySqlDataAdapter.SelectCommand = MySelectCmd;
MySqlDataAdapter.UpdateCommand = MyUpdateCmd;
MySqlDataAdapter.InsertCommand = MyInsertCmd;
MySqlDataAdapter.DeleteCommand = MyDeleteCmd;
}
Note sur les paramètres d'Update : Le paramètre @CodeEns est configuré avec SourceVersion = DataRowVersion.Original. Ceci est essentiel pour les mises à jour optimistes, permettant de localiser l'enregistrement original même si la clé primaire a été modifiée dans le DataSet avant la mise à jour, ou pour s'assurer qu'une ligne n'a pas été modifiée par un autre utilisateur avant la tentative de mise à jour.
Méthode SelectEnreg (Sélectionner les enregistrements)
Cette méthode remplit le DataSet avec les données de la table "Enseignants" et lie ces données à un contrôle DataGrid (supposé nommé DgEnseignant) pour l'affichage.
private void SelectEnreg(object sender, System.EventArgs e)
{
MySqlDataAdapter.Fill(MyDataSet, "Enseignants");
NbEnreg = MyDataSet.Tables["Enseignants"].Rows.Count;
DgEnseignant.SetDataBinding(MyDataSet, "Enseignants");
}
Méthode AfficheEnreg (Afficher un enregistrement)
Affiche les détails de l'enregistrement courant (identifié par l'index NumEnreg) dans des champs de texte de l'interface utilisateur (par exemple, TxtCodeEns, TxtNom, etc.). Elle met également à jour un champ affichant la position de l'enregistrement courant par rapport au nombre total d'enregistrements.
private void AfficheEnreg(int Num)
{
MyWorkRow = MyDataSet.Tables["Enseignants"].Rows[NumEnreg];
TxtCodeEns.Text = MyWorkRow["CodeEnseignant"].ToString();
TxtNom.Text = MyWorkRow["Nom"].ToString();
TxtPrenom.Text = MyWorkRow["Prenom"].ToString();
TxtDateNaiss.Text = MyWorkRow["DateNaissance"].ToString();
TxtNumNbEnreg.Text = (NumEnreg + 1).ToString() + "/ " + NbEnreg.ToString();
}
Méthodes de Navigation (Premier, Précédent, Suivant, Dernier)
Ces méthodes permettent de naviguer à travers les enregistrements chargés dans le DataSet et d'afficher les informations de chaque enseignant. Des messages d'alerte s'affichent si l'utilisateur tente de naviguer au-delà du premier ou du dernier enregistrement.
private void PremierEnreg(object sender, System.EventArgs e)
{
NumEnreg = 0;
AfficheEnreg(NumEnreg);
}
private void PrecedentEnreg(object sender, System.EventArgs e)
{
if (NumEnreg > 0)
{
NumEnreg--;
AfficheEnreg(NumEnreg);
}
else
MessageBox.Show("Vous êtes sur le premier enregistrement");
}
private void SuivantEnreg(object sender, System.EventArgs e)
{
if (NumEnreg < NbEnreg - 1)
{
NumEnreg++;
AfficheEnreg(NumEnreg);
}
else
{
MessageBox.Show("Vous êtes sur le dernier enregistrement");
TxtCodeEns.Clear();
TxtNom.Clear();
TxtPrenom.Clear();
TxtDateNaiss.Clear();
}
}
private void DernierEnreg(object sender, System.EventArgs e)
{
NumEnreg = NbEnreg - 1;
AfficheEnreg(NumEnreg);
}
Méthode Deconnecter
Ferme la connexion active à la base de données, libérant ainsi les ressources.
private void Deconnecter(object sender, System.EventArgs e)
{
MySqlConn.Close();
}
Méthode InsertEnreg (Insérer un enregistrement)
Crée une nouvelle ligne (DataRow) dans la table "Enseignants" du DataSet, y ajoute les données saisies dans l'interface utilisateur, puis ajoute cette ligne à la collection de lignes du DataSet. Enfin, elle utilise le SqlDataAdapter pour envoyer cette nouvelle ligne à la base de données.
private void InsertEnreg(object sender, System.EventArgs e)
{
MyWorkRow = MyDataSet.Tables["Enseignants"].NewRow();
MyWorkRow["CodeEnseignant"] = byte.Parse(TxtCodeEns.Text);
MyWorkRow["Nom"] = TxtNom.Text;
MyWorkRow["Prenom"] = TxtPrenom.Text;
MyWorkRow["DateNaissance"] = DateTime.Parse(TxtDateNaiss.Text);
MyDataSet.Tables["Enseignants"].Rows.Add(MyWorkRow);
MySqlDataAdapter.Update(MyDataSet, "Enseignants");
NbEnreg++;
NumEnreg++;
TxtNumNbEnreg.Text = (NumEnreg + 1).ToString() + "/ " + NbEnreg.ToString();
}
Méthode UpdateEnreg (Mettre à jour un enregistrement)
Modifie la ligne courante dans le DataSet (celle correspondant à NumEnreg) avec les nouvelles données saisies dans les champs de texte, puis synchronise ces modifications avec la base de données via le SqlDataAdapter.
private void UpdateEnreg(object sender, System.EventArgs e)
{
MyWorkRow = MyDataSet.Tables["Enseignants"].Rows[NumEnreg];
MyWorkRow["CodeEnseignant"] = byte.Parse(TxtCodeEns.Text);
MyWorkRow["Nom"] = TxtNom.Text;
MyWorkRow["Prenom"] = TxtPrenom.Text;
MyWorkRow["DateNaissance"] = DateTime.Parse(TxtDateNaiss.Text);
MySqlDataAdapter.Update(MyDataSet, "Enseignants");
TxtNumNbEnreg.Text = (NumEnreg + 1).ToString() + "/ " + NbEnreg.ToString();
}
Méthode DeleteEnreg (Supprimer un enregistrement)
Marque la ligne courante pour suppression dans le DataSet en appelant sa méthode Delete(), puis utilise le SqlDataAdapter pour appliquer cette suppression à la base de données. Le nombre d'enregistrements est ajusté et l'affichage mis à jour.
private void DeleteEnreg(object sender, System.EventArgs e)
{
MyDataSet.Tables["Enseignants"].Rows[NumEnreg].Delete();
MySqlDataAdapter.Update(MyDataSet, "Enseignants");
NbEnreg--;
if (NumEnreg == NbEnreg)
NumEnreg = NbEnreg - 1;
AfficheEnreg(NumEnreg);
}
Exercice Pratique 2 : Gestion Simplifiée des Enseignants
Cette section présente une interface utilisateur simplifiée pour la gestion des données, axée sur la consultation et la mise à jour globale de la base.
Description de l'Interface Utilisateur Simplifiée
Cette deuxième interface propose une approche plus simple pour interagir avec la base de données. La structure des menus est la suivante :
Menu "Connexion"
- Connecter : Établit la connexion à la base de données.
- Déconnecter : Ferme la connexion à la base de données.
Menu "Action"
- Consulter la base : Charge les données dans un
DataSetpour consultation. - Mettre à jour la base : Enregistre toutes les modifications en attente du
DataSetdans la base de données.
Implémentation des Gestionnaires d'Événements (Simplifiée)
Les variables globales sont similaires à l'exercice précédent, mais la logique des méthodes est adaptée pour cette interface simplifiée.
Déclarations des Variables Globales
static SqlConnection MySqlConn;
static SqlCommand MySelectCmd, MyInsertCmd, MyUpdateCmd, MyDeleteCmd;
static SqlDataAdapter MySqlDataAdapter;
static DataSet MyDataSet;
static string MyStrConn, MyStrSelect, MyStrInsert, MyStrUpdate, MyStrDelete;
Méthode Connecter (avec gestion d'erreurs)
Cette version de la méthode Connecter inclut un bloc try-catch pour gérer les exceptions potentielles lors de l'établissement de la connexion ou de la préparation des commandes SQL. Ceci est une bonne pratique pour rendre l'application plus robuste face aux erreurs de base de données.
private void Connecter(object sender, System.EventArgs e)
{
try
{
MyStrConn = "Server = Localhost; Integrated Security = SSPI; Initial Catalog = SQLNotation";
MySqlConn = new SqlConnection(MyStrConn);
MySqlConn.Open();
MyStrSelect = "SELECT CodeEnseignant, Nom, Prenom, DateNaissance FROM Enseignants";
MySelectCmd = new SqlCommand(MyStrSelect, MySqlConn);
MyStrInsert = "INSERT INTO Enseignants " +
"(CodeEnseignant, Nom, Prenom, DateNaissance) " +
"Values (@CodeEnseignant, @Nom, @Prenom, @DateNaiss)";
MyInsertCmd = new SqlCommand(MyStrInsert, MySqlConn);
MyInsertCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyInsertCmd.Parameters.Add("@Nom", SqlDbType.VarChar, 25, "Nom");
MyInsertCmd.Parameters.Add("@Prenom", SqlDbType.VarChar, 15, "Prenom");
MyInsertCmd.Parameters.Add("@DateNaiss", SqlDbType.SmallDateTime, 0, "DateNaissance");
MyStrUpdate = "UPDATE Enseignants SET CodeEnseignant=@CodeEnseignant, " +
"Nom = @Nom, Prenom = @Prenom, DateNaissance=@DateNaiss " +
"Where CodeEnseignant = @OldCodeEns";
MyUpdateCmd = new SqlCommand(MyStrUpdate, MySqlConn);
MyUpdateCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyUpdateCmd.Parameters.Add("@Nom", SqlDbType.VarChar, 25, "Nom");
MyUpdateCmd.Parameters.Add("@Prenom", SqlDbType.VarChar, 15, "Prenom");
MyUpdateCmd.Parameters.Add("@DateNaiss", SqlDbType.SmallDateTime, 0, "DateNaissance");
SqlParameter WorkParam = MyUpdateCmd.Parameters.Add("@OldCodeEns", SqlDbType.TinyInt);
WorkParam.SourceColumn = "CodeEnseignant";
WorkParam.SourceVersion = DataRowVersion.Original;
MyStrDelete = "DELETE Enseignants WHERE CodeEnseignant = @CodeEnseignant";
MyDeleteCmd = new SqlCommand(MyStrDelete, MySqlConn);
MyDeleteCmd.Parameters.Add("@CodeEnseignant", SqlDbType.TinyInt, 0, "CodeEnseignant");
MyDataSet = new DataSet();
MySqlDataAdapter = new SqlDataAdapter();
MySqlDataAdapter.SelectCommand = MySelectCmd;
MySqlDataAdapter.UpdateCommand = MyUpdateCmd;
MySqlDataAdapter.InsertCommand = MyInsertCmd;
MySqlDataAdapter.DeleteCommand = MyDeleteCmd;
}
catch (Exception MyE)
{
MessageBox.Show(MyE.Message);
}
}
Méthode Consulter
Cette méthode est similaire à SelectEnreg ; elle remplit le DataSet avec les données de la table "Enseignants" et lie ces données à un contrôle DataGrid (DgEnseignant).
private void Consulter(object sender, System.EventArgs e)
{
MySqlDataAdapter.Fill(MyDataSet, "Enseignants");
DgEnseignant.SetDataBinding(MyDataSet, "Enseignants");
}
Méthode Deconnecter
Ferme la connexion à la base de données.
private void Deconnecter(object sender, System.EventArgs e)
{
MySqlConn.Close();
}
Méthode MettreÀJourLaBase (avec gestion d'erreurs)
Cette méthode applique toutes les modifications (insertions, mises à jour, suppressions) en attente dans le DataSet à la base de données. Elle utilise un bloc try-catch pour intercepter et afficher les erreurs éventuelles lors de la mise à jour, ce qui est crucial pour un traitement robuste des transactions de base de données.
private void MettreAjourLaBase(object sender, System.EventArgs e)
{
try
{
MySqlDataAdapter.Update(MyDataSet, "Enseignants");
}
catch (Exception MyE)
{
MessageBox.Show (MyE.Message);
}
}
Foire Aux Questions (FAQ)
1. Qu'est-ce qu'ADO.NET et à quoi sert-il ?
ADO.NET est un ensemble de classes .NET qui permet aux applications de se connecter à des bases de données et de manipuler des données. Il est principalement utilisé pour construire des applications qui nécessitent une interaction avec des sources de données, comme des bases de données relationnelles (SQL Server, Oracle, MySQL, etc.) ou des fichiers XML, en fournissant une architecture flexible et évolutive pour l'accès aux données.
2. Quelle est la différence entre un DataSet et un SqlDataAdapter ?
Le DataSet est une représentation en mémoire et déconnectée des données de la base de données. Il peut contenir une ou plusieurs tables (DataTable), des vues et des relations entre elles. Il permet de manipuler les données localement sans connexion constante à la base. Le SqlDataAdapter, quant à lui, est le composant clé qui assure la communication entre le DataSet et la base de données. Il utilise les commandes SQL (SELECT, INSERT, UPDATE, DELETE) pour remplir le DataSet à partir de la base de données et pour propager les modifications du DataSet vers la base de données.
3. Comment gérer les erreurs lors de l'interaction avec une base de données en C# ?
La gestion des erreurs est cruciale pour la robustesse des applications. En C# avec ADO.NET, les blocs try-catch sont utilisés pour intercepter les exceptions qui peuvent survenir lors des opérations de base de données. Ces exceptions peuvent être dues à des problèmes de connexion (réseau, authentification), des erreurs SQL (syntaxe, violations de contraintes), ou d'autres problèmes liés aux données. L'utilisation de MessageBox.Show(MyE.Message) permet d'informer l'utilisateur des erreurs de manière simple, mais pour des applications de production, une journalisation plus avancée et une gestion des erreurs plus raffinée seraient nécessaires.