Créer une application de données simple à l’aide d’ADO.NET

Remarque

Les jeux de données et les classes associées sont des technologies .NET Framework héritées qui datent du début des années 2000. Elles permettent aux applications d’utiliser des données en mémoire pendant que les applications sont déconnectées de la base de données. Elles sont particulièrement utiles aux applications qui permettent aux utilisateurs de modifier des données, et de rendre ces changements persistants dans la base de données. Même si les jeux de données sont une technologie très efficace, nous vous recommandons d’utiliser Entity Framework Core pour les nouvelles applications .NET. Entity Framework offre un moyen plus naturel d’utiliser des données tabulaires en tant que modèles objet. De plus, il présente une interface de programmation plus simple.

Quand vous créez une application qui manipule les données d’une base de données, vous effectuez des tâches élémentaires, comme définir les chaînes de connexion, insérer les données et exécuter les procédures stockées. En suivant cette rubrique, vous découvrirez comment interagir avec une base de données à partir d’une application « formulaires sur données » Windows Forms simple à l’aide de Visual C# ou Visual Basic et de ADO.NET. Toutes les technologies de données .NET, y compris les jeux de données, LINQ to SQL et Entity Framework, effectuent des étapes très similaires à celles présentées dans cet article.

Cet article montre un moyen simple d’extraire rapidement les données d’une base de données. Si votre application doit modifier les données de manière non triviale et mettre à jour la base de données, vous devriez envisager d’utiliser Entity Framework et d’utiliser la liaison de données pour synchroniser automatiquement les contrôles d’interface utilisateur pour modifier les données sous-jacentes.

Important

Pour que le code reste simple, il n’inclut pas la gestion des exceptions prête à la production.

Notes

Le code complet de ce tutoriel est accessible dans le référentiel GitHub de documentation Visual Studio en C# et Visual Basic.

Prérequis

Pour créer l'application, vous aurez besoin des éléments suivants :

  • Avec les charges de travail Développement de bureau .NET et Stockage et traitement des données installées dans Visual Studio. Pour les installer, ouvrez Visual Studio Installer et choisissez Modifier (ou Plus>Modifier) en regard de la version de Visual Studio que vous souhaitez modifier.

  • SQL Server Express LocalDB. Si vous n’avez pas SQL Server Express LocalDB, vous pouvez l’installer à partir de la page de téléchargement de SQL Server.

Cette rubrique suppose que vous connaissez les fonctionnalités de base de l’IDE Visual Studio et que vous pouvez créer une application Windows Forms, ajouter des formulaires au projet, placer des boutons et d’autres contrôles sur les formulaires, définir les propriétés des contrôles et coder des événements simples. Si vous n’êtes pas à l’aise avec ces tâches, nous vous suggérons de suivre le tutoriel Créer une application Windows Forms dans Visual Studio avec Visual Basic ou le tutoriel Créer une application Windows Forms dans Visual Studio avec C# avant de commencer cette procédure pas à pas.

Installer l'exemple de base de données

Créez l’exemple de base de données en procédant comme suit :

  1. Dans Visual Studio, ouvrez la fenêtre Explorateur de serveurs.

  2. Faites un clic droit sur Connexions de données et choisissez Créer une base de données SQL Server.

  3. Dans la zone de texte Nom du serveur, entrez (localdb)\mssqllocaldb.

  4. Dans la zone de texte Nouveau nom de base de données, entrez Ventes, puis cliquez sur OK.

    La base de données Ventes vide est créée et ajoutée au nœud Connexions de données dans l’Explorateur de serveurs.

  5. Faites un clic droit sur la connexion de données Ventes et sélectionnez Nouvelle requête.

    Une fenêtre d’éditeur de requête s’ouvre.

  6. Copiez le script Ventes Transact-SQL dans votre Presse-papiers.

  7. Collez le script T-SQL dans l’éditeur de requête, puis cliquez sur le bouton Exécuter.

    Après un court laps de temps, l’exécution de la requête se termine et les objets de base de données sont créés. La base de données contient deux tables : Clients et Commandes. Initialement, les tables ne contiennent pas de données, mais vous pourrez en ajouter lorsque vous exécuterez l'application que vous allez créer. La base de données contient également quatre procédures stockées simples.

Créer les formulaires et ajouter les contrôles

  1. Créez un projet C# ou Visual Basic à l’aide du modèle Application Windows Forms (.NET Framework), puis nommez-le SimpleDataApp.

    Visual Studio crée le projet et plusieurs fichiers, dont un formulaire Windows vide nommé Form1.

  2. Ajoutez deux formulaires Windows à votre projet afin qu’il comporte trois formulaires, puis attribuez-leur les noms suivants :

    • Navigation

    • NewCustomer

    • FillOrCancel

  3. Pour chaque formulaire, ajoutez les zones de texte, les boutons et les autres contrôles indiqués dans les illustrations suivantes. Pour chaque contrôle, définissez les propriétés que les tables décrivent.

    Remarque

    La zone de groupe et les contrôles d'étiquette ajoutent de la clarté mais ne sont pas utilisés dans le code.

    Formulaire Navigation

    Boîte de dialogue Navigation

Contrôles du formulaire Navigation Propriétés
Bouton Name = btnGoToAdd
Bouton Name = btnGoToFillOrCancel
Bouton Name = btnExit

Formulaire NewCustomer

Ajouter un nouveau client et passer une commande

Contrôles du formulaire NewCustomer Propriétés
TextBox Name = txtCustomerName
TextBox Name = txtCustomerID

Readonly = True
Bouton Name = btnCreateAccount
NumericUpdown DecimalPlaces = 0

Maximum = 5000

Name = numOrderAmount
DateTimePicker Format = Short

Name = dtpOrderDate
Bouton Name = btnPlaceOrder
Bouton Name = btnAddAnotherAccount
Bouton Name = btnAddFinish

Formulaire FillOrCancel

remplir ou annuler les commandes

Contrôles du formulaire FillOrCancel Propriétés
TextBox Name = txtOrderID
Bouton Name = btnFindByOrderID
DateTimePicker Format = Short

Name = dtpFillDate
DataGridView Name = dgvCustomerOrders

Readonly = True

RowHeadersVisible = False
Bouton Name = btnCancelOrder
Bouton Name = btnFillOrder
Bouton Name = btnFinishUpdates

Stocker la chaîne de connexion

Quand votre application tente d'ouvrir une connexion à la base de données, elle doit avoir accès à la chaîne de connexion. Pour éviter d'entrer la chaîne manuellement sur chaque formulaire, stockez la chaîne dans le fichier App.config de votre projet, puis créez une méthode qui retourne la chaîne quand elle est appelée depuis un formulaire de votre application.

Vous trouverez la chaîne de connexion en faisant un clic droit sur la connexion de données Ventes dans Explorateur de serveurs et en choisissant Propriétés. Recherchez la propriété ConnectionString, puis utilisez Ctrl+A, Ctrl+C pour sélectionner et copier la chaîne dans le Presse-papiers.

  1. Si vous utilisez C#, dans Explorateur de solutions, développez le nœud Propriétés sous le projet, puis ouvrez le fichier Settings.settings. Si vous utilisez Visual Basic, dans Explorateur de solutions, cliquez sur Afficher tous les fichiers, développez le nœud Mon projet, puis ouvrez le fichier Settings.settings.

  2. Dans la colonne Nom, entrez connString.

  3. Dans la liste Type, sélectionnez (Chaîne de connexion).

  4. Dans la liste Étendue, sélectionnez Application.

  5. Dans la colonne Valeur, entrez votre chaîne de connexion (sans guillemets extérieurs), puis enregistrez vos modifications.

    Capture d’écran de la chaîne de connexion dans Settings.settings

Notes

Dans une application réelle, vous devez stocker la chaîne de connexion en toute sécurité, comme décrit dans Chaînes de connexion et fichiers de configuration.

Écrire le code des formulaires

Cette section contient de brèves présentations de ce que fait chaque formulaire. Elle fournit également le code qui définit la logique sous-jacente lorsqu’un d’un clic sur un bouton du formulaire.

Le formulaire Navigation s'ouvre quand vous exécutez l'application. Le bouton Ajouter un compte ouvre le formulaire NewCustomer. Le bouton Remplir ou annuler les commandes ouvre le formulaire FillOrCancel. Le bouton Quitter ferme l’application.

Faire du formulaire Navigation le formulaire de démarrage

Si vous utilisez C#, dans l’Explorateur de solutions, ouvrez Program.cs, puis remplacez la ligne Application.Run par Application.Run(new Navigation());

Si vous utilisez Visual Basic, dans Explorateur de solutions, ouvrez la fenêtre Propriétés, sélectionnez l’onglet Application, puis sélectionnez SimpleDataApp.Navigation dans la liste Formulaire de démarrage.

Créer des gestionnaires d’événements générés automatiquement

Double-cliquez sur les trois boutons du formulaire de navigation pour créer des méthodes de gestionnaire d’événements vides. Le double-clic sur les boutons ajoute également du code généré automatiquement dans le fichier de code concepteur qui permet à un clic de déclencher un événement.

Remarque

Si vous ignorez l’action de double-clic dans le concepteur et copiez et collez simplement le code dans vos fichiers de code, n’oubliez pas de définir le gestionnaire d’événements sur la méthode appropriée. Vous pouvez le faire dans la fenêtre Propriétés. Basculez vers l’onglet Événements (utilisez le bouton de barre d’outils éclair) et recherchez le gestionnaire Clic.

Ajouter du code pour la logique de formulaire de navigation

Dans la page de codes du formulaire de navigation, complétez les corps de méthode des trois gestionnaires d’événements de clic sur le bouton, comme indiqué dans le code suivant.

/// <summary>
/// Opens the NewCustomer form as a dialog box,
/// which returns focus to the calling form when it is closed. 
/// </summary>
private void btnGoToAdd_Click(object sender, EventArgs e)
{
    Form frm = new NewCustomer();
    frm.Show();
}

/// <summary>
/// Opens the FillorCancel form as a dialog box. 
/// </summary>
private void btnGoToFillOrCancel_Click(object sender, EventArgs e)
{
    Form frm = new FillOrCancel();
    frm.ShowDialog();
}

/// <summary>
/// Closes the application (not just the Navigation form).
/// </summary>
private void btnExit_Click(object sender, EventArgs e)
{
    this.Close();
}

Notes

Le code de ce tutoriel est disponible en C# et Visual Basic. Pour basculer le langage de code de cette page entre C# et Visual Basic, utilisez le sélecteur de langage de code en haut de chaque exemple de code.

Formulaire NewCustomer

Lorsque vous entrez un nom de client et sélectionnez le bouton Créer un compte, le formulaire NewCustomer crée un compte client et SQL Server retourne une valeur IDENTITY comme nouvel identifiant client. Vous pouvez ensuite passer une commande pour le nouveau compte en spécifiant un montant et une date de commande et en sélectionnant le bouton Passer une commande.

Créer des gestionnaires d’événements générés automatiquement

Créez un gestionnaire d’événements Click vide pour chaque bouton du formulaire NewCustomer en double-cliquant sur chacun des quatre boutons. Le double-clic sur les boutons ajoute également du code généré automatiquement dans le fichier de code concepteur qui permet à un clic de déclencher un événement.

Ajouter du code pour la logique de formulaire NewCustomer

Pour terminer la logique de formulaire NewCustomer, procédez comme suit.

  1. Placez l’espace de noms System.Data.SqlClient dans l’étendue afin que vous n’ayez pas à qualifier pleinement les noms de ses membres.

    using System.Data.SqlClient;
    
  2. Ajoutez certaines variables et méthodes d’assistance à la classe, comme indiqué dans le code suivant.

    // Storage for IDENTITY values returned from database.
    private int parsedCustomerID;
    private int orderID;
    
    /// <summary>
    /// Verifies that the customer name text box is not empty.
    /// </summary>
    private bool IsCustomerNameValid()
    {
        if (txtCustomerName.Text == "")
        {
            MessageBox.Show("Please enter a name.");
            return false;
        }
        else
        {
            return true;
        }
    }
    
    /// <summary>
    /// Verifies that a customer ID and order amount have been provided.
    /// </summary>
    private bool IsOrderDataValid()
    {
        // Verify that CustomerID is present.
        if (txtCustomerID.Text == "")
        {
            MessageBox.Show("Please create customer account before placing order.");
            return false;
        }
        // Verify that Amount isn't 0.
        else if ((numOrderAmount.Value < 1))
        {
            MessageBox.Show("Please specify an order amount.");
            return false;
        }
        else
        {
            // Order can be submitted.
            return true;
        }
    }
    
    /// <summary>
    /// Clears the form data.
    /// </summary>
    private void ClearForm()
    {
        txtCustomerName.Clear();
        txtCustomerID.Clear();
        dtpOrderDate.Value = DateTime.Now;
        numOrderAmount.Value = 0;
        this.parsedCustomerID = 0;
    }
    
  3. Complétez les corps de méthode pour les quatre gestionnaires d’événements de clic sur le bouton, comme indiqué dans le code suivant.

    /// <summary>
    /// Creates a new customer by calling the Sales.uspNewCustomer stored procedure.
    /// </summary>
    private void btnCreateAccount_Click(object sender, EventArgs e)
    {
        if (IsCustomerNameValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create a SqlCommand, and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add input parameter for the stored procedure and specify what to use as its value.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40));
                    sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text;
    
                    // Add the output parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int));
                    sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output;
    
                    try
                    {
                        connection.Open();
    
                        // Run the stored procedure.
                        sqlCommand.ExecuteNonQuery();
    
                        // Customer ID is an IDENTITY value from the database.
                        this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value;
    
                        // Put the Customer ID value into the read-only text box.
                        this.txtCustomerID.Text = Convert.ToString(parsedCustomerID);
                    }
                    catch
                    {
                        MessageBox.Show("Customer ID was not returned. Account could not be created.");
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Calls the Sales.uspPlaceNewOrder stored procedure to place an order.
    /// </summary>
    private void btnPlaceOrder_Click(object sender, EventArgs e)
    {
        // Ensure the required input is present.
        if (IsOrderDataValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create SqlCommand and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the @CustomerID input parameter, which was obtained from uspNewCustomer.
                    sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int));
                    sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID;
    
                    // Add the @OrderDate input parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8));
                    sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value;
    
                    // Add the @Amount order amount input parameter.
                    sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int));
                    sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value;
    
                    // Add the @Status order status input parameter.
                    // For a new order, the status is always O (open).
                    sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1));
                    sqlCommand.Parameters["@Status"].Value = "O";
    
                    // Add the return value for the stored procedure, which is  the order ID.
                    sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int));
                    sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue;
    
                    try
                    {
                        //Open connection.
                        connection.Open();
    
                        // Run the stored procedure.
                        sqlCommand.ExecuteNonQuery();
    
                        // Display the order number.
                        this.orderID = (int)sqlCommand.Parameters["@RC"].Value;
                        MessageBox.Show("Order number " + this.orderID + " has been submitted.");
                    }
                    catch
                    {
                        MessageBox.Show("Order could not be placed.");
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Clears the form data so another new account can be created.
    /// </summary>
    private void btnAddAnotherAccount_Click(object sender, EventArgs e)
    {
        this.ClearForm();
    }
    
    /// <summary>
    /// Closes the form/dialog box.
    /// </summary>
    private void btnAddFinish_Click(object sender, EventArgs e)
    {
        this.Close();
    }
    

Formulaire FillOrCancel

Le formulaire FillOrCancel exécute une requête pour retourner une commande quand vous entrez une référence de commande et que vous cliquez sur le bouton Rechercher la commande. La ligne retournée apparaît dans une grille de données en lecture seule. Vous pouvez marquer la commande comme annulée (X) si vous sélectionnez le bouton Annuler la commande, ou vous pouvez marquer la commande comme rempli (F) si vous sélectionnez le bouton Exécuter la commande. Si vous sélectionnez à nouveau le bouton Rechercher la commande, la ligne mise à jour s’affiche.

Créer des gestionnaires d’événements générés automatiquement

Créez des gestionnaires d’événements Click vides pour les quatre boutons du formulaire FillOrCancel en double-cliquant sur les boutons. Le double-clic sur les boutons ajoute également du code généré automatiquement dans le fichier de code concepteur qui permet à un clic de déclencher un événement.

Ajouter du code pour la logique de formulaire FillOrCancel

Pour terminer la logique de formulaire FillOrCancel, procédez comme suit.

  1. Placez les deux espaces de noms suivants dans l’étendue afin que vous n’ayez pas à qualifier pleinement les noms de leurs membres.

    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    
  2. Ajoutez une variable et une méthode d’assistance à la classe, comme indiqué dans le code suivant.

    // Storage for the order ID value.
    private int parsedOrderID;
    
    /// <summary>
    /// Verifies that an order ID is present and contains valid characters.
    /// </summary>
    private bool IsOrderIDValid()
    {
        // Check for input in the Order ID text box.
        if (txtOrderID.Text == "")
        {
            MessageBox.Show("Please specify the Order ID.");
            return false;
        }
    
        // Check for characters other than integers.
        else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$"))
        {
            // Show message and clear input.
            MessageBox.Show("Customer ID must contain only numbers.");
            txtOrderID.Clear();
            return false;
        }
        else
        {
            // Convert the text in the text box to an integer to send to the database.
            parsedOrderID = Int32.Parse(txtOrderID.Text);
            return true;
        }
    }
    
  3. Complétez les corps de méthode pour les quatre gestionnaires d’événements de clic sur le bouton, comme indiqué dans le code suivant.

    /// <summary>
    /// Executes a t-SQL SELECT statement to obtain order data for a specified
    /// order ID, then displays it in the DataGridView on the form.
    /// </summary>
    private void btnFindByOrderID_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Define a t-SQL query string that has a parameter for orderID.
                const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID";
    
                // Create a SqlCommand object.
                using (SqlCommand sqlCommand = new SqlCommand(sql, connection))
                {
                    // Define the @orderID parameter and set its value.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    try
                    {
                        connection.Open();
    
                        // Run the query by calling ExecuteReader().
                        using (SqlDataReader dataReader = sqlCommand.ExecuteReader())
                        {
                            // Create a data table to hold the retrieved data.
                            DataTable dataTable = new DataTable();
    
                            // Load the data from SqlDataReader into the data table.
                            dataTable.Load(dataReader);
    
                            // Display the data from the data table in the data grid view.
                            this.dgvCustomerOrders.DataSource = dataTable;
    
                            // Close the SqlDataReader.
                            dataReader.Close();
                        }
                    }
                    catch
                    {
                        MessageBox.Show("The requested order could not be loaded into the form.");
                    }
                    finally
                    {
                        // Close the connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Cancels an order by calling the Sales.uspCancelOrder
    /// stored procedure on the database.
    /// </summary>
    private void btnCancelOrder_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create the SqlCommand object and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the order ID input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    try
                    {
                        // Open the connection.
                        connection.Open();
    
                        // Run the command to execute the stored procedure.
                        sqlCommand.ExecuteNonQuery();
                    }
                    catch
                    {
                        MessageBox.Show("The cancel operation was not completed.");
                    }
                    finally
                    {
                        // Close connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Fills an order by calling the Sales.uspFillOrder stored
    /// procedure on the database.
    /// </summary>
    private void btnFillOrder_Click(object sender, EventArgs e)
    {
        if (IsOrderIDValid())
        {
            // Create the connection.
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString))
            {
                // Create command and identify it as a stored procedure.
                using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection))
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
    
                    // Add the order ID input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int));
                    sqlCommand.Parameters["@orderID"].Value = parsedOrderID;
    
                    // Add the filled date input parameter for the stored procedure.
                    sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8));
                    sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value;
    
                    try
                    {
                        connection.Open();
    
                        // Execute the stored procedure.
                        sqlCommand.ExecuteNonQuery();
                    }
                    catch
                    {
                        MessageBox.Show("The fill operation was not completed.");
                    }
                    finally
                    {
                        // Close the connection.
                        connection.Close();
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Closes the form.
    /// </summary>
    private void btnFinishUpdates_Click(object sender, EventArgs e)
    {
        this.Close();
    }
    

Tester votre application

Exécutez l’application et essayez de créer quelques clients et commandes pour vérifier que tout fonctionne comme prévu. Pour vérifier que la base de données est mise à jour avec vos modifications, ouvrez le nœud Tableaux dans l’Explorateur de serveurs, faites un clic droit sur les nœuds Clients et Commandes, puis choisissez Afficher les données de tableau.