Partager via


Réalisation de mises à jour par lots (C#)

par Scott Mitchell

Télécharger le PDF

Découvrez comment créer une DataList entièrement modifiable où tous ses éléments sont en mode édition et dont les valeurs peuvent être enregistrées en cliquant sur un bouton « Tout mettre à jour » sur la page.

Introduction

Dans le tutoriel précédent , nous avons examiné comment créer une datalist au niveau élément. Comme le GridView modifiable standard, chaque élément de la Liste de données comprenait un bouton Modifier qui, en cas de clic, rendait l’élément modifiable. Bien que cette modification au niveau de l’élément fonctionne bien pour les données qui ne sont mises à jour qu’occasionnellement, certains scénarios d’utilisation obligent l’utilisateur à modifier de nombreux enregistrements. Si un utilisateur a besoin de modifier des dizaines d’enregistrements et est obligé de cliquer sur Modifier, d’apporter leurs modifications et de cliquer sur Mettre à jour pour chacun d’eux, la quantité de clics peut entraver sa productivité. Dans de telles situations, une meilleure option consiste à fournir une DataList entièrement modifiable, où tous ses éléments sont en mode édition et dont les valeurs peuvent être modifiées en cliquant sur un bouton Mettre à jour tout sur la page (voir figure 1).

Chaque élément d’une liste de données entièrement modifiable peut être modifié

Figure 1 : Chaque élément d’une liste de données entièrement modifiable peut être modifié (cliquez pour afficher l’image en taille réelle)

Dans ce tutoriel, nous allons examiner comment permettre aux utilisateurs de mettre à jour les informations d’adresse des fournisseurs à l’aide d’une liste de données entièrement modifiable.

Étape 1 : Créer l’interface utilisateur modifiable dans l’élément ItemTemplate de DataList

Dans le tutoriel précédent, où nous avons créé une datalist modifiable standard au niveau de l’élément, nous avons utilisé deux modèles :

  • ItemTemplate contenait l’interface utilisateur en lecture seule (les contrôles Label Web pour afficher le nom et le prix de chaque produit).
  • EditItemTemplate contenait l’interface utilisateur en mode édition (les deux contrôles Web TextBox).

La propriété DataList s EditItemIndex dicte ce qui DataListItem (le cas échéant) est rendu à l’aide de EditItemTemplate. En particulier, le dont ItemIndex la DataListItem valeur correspond à la propriété DataList s EditItemIndex est rendu à l’aide de EditItemTemplate. Ce modèle fonctionne bien lorsqu’un seul élément peut être modifié à la fois, mais se désagrège lors de la création d’une DataList entièrement modifiable.

Pour une DataList entièrement modifiable, nous voulons que tous les s soient rendus à l’aide DataListItem de l’interface modifiable. Le moyen le plus simple d’y parvenir consiste à définir l’interface modifiable dans .ItemTemplate Pour modifier les informations d’adresse des fournisseurs, l’interface modifiable contient le nom du fournisseur sous forme de texte, puis textboxes pour les valeurs d’adresse, de ville et de pays/région.

Commencez par ouvrir la BatchUpdate.aspx page, ajoutez un contrôle DataList et définissez sa ID propriété sur Suppliers. À partir de la balise active de DataList, choisissez d’ajouter un nouveau contrôle ObjectDataSource nommé SuppliersDataSource.

Créer un objetDataSource nommé SuppliersDataSource

Figure 2 : Créer un objetDataSource nommé SuppliersDataSource (cliquer pour afficher l’image en taille réelle)

Configurez ObjectDataSource pour récupérer des données à l’aide de la SuppliersBLL méthode class s GetSuppliers() (voir figure 3). Comme dans le tutoriel précédent, plutôt que de mettre à jour les informations du fournisseur via ObjectDataSource, nous allons travailler directement avec la couche logique métier. Par conséquent, définissez la liste déroulante sur (Aucun) dans l’onglet UPDATE (voir figure 4).

Récupérer des informations sur le fournisseur à l’aide de la méthode GetSuppliers()

Figure 3 : Récupérer des informations sur le fournisseur à l’aide de la GetSuppliers() méthode (Cliquer pour afficher l’image en taille réelle)

Définissez la liste Drop-Down sur (Aucun) dans l’onglet UPDATE

Figure 4 : Définissez la liste des Drop-Down sur (Aucun) sous l’onglet UPDATE (Cliquer pour afficher l’image en taille réelle)

Une fois l’Assistant terminé, Visual Studio génère automatiquement les DataList pour afficher chaque champ de ItemTemplate données retourné par la source de données dans un contrôle Label Web. Nous devons modifier ce modèle afin qu’il fournisse l’interface d’édition à la place. Le ItemTemplate peut être personnalisé via le Designer à l’aide de l’option Modifier les modèles à partir de la balise active de DataList ou directement via la syntaxe déclarative.

Prenez un moment pour créer une interface de modification qui affiche le nom du fournisseur sous forme de texte, mais inclut des zones de texte pour les valeurs d’adresse, de ville et de pays/région du fournisseur. Après avoir apporté ces modifications, la syntaxe déclarative de votre page doit ressembler à ce qui suit :

<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID"
    DataSourceID="SuppliersDataSource">
    <ItemTemplate>
        <h4><asp:Label ID="CompanyNameLabel" runat="server"
            Text='<%# Eval("CompanyName") %>' /></h4>
        <table border="0">
            <tr>
                <td class="SupplierPropertyLabel">Address:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="Address" runat="server"
                        Text='<%# Eval("Address") %>' />
                </td>
            </tr>
            <tr>
                <td class="SupplierPropertyLabel">City:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="City" runat="server"
                        Text='<%# Eval("City") %>' />
                </td>
            </tr>
            <tr>
                <td class="SupplierPropertyLabel">Country:</td>
                <td class="SupplierPropertyValue">
                    <asp:TextBox ID="Country" runat="server"
                        Text='<%# Eval("Country") %>' />
                </td>
            </tr>
        </table>
        <br />
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

Notes

Comme dans le tutoriel précédent, l’état d’affichage de la datalist de ce didacticiel doit être activé.

Dans le ItemTemplate J’utilise deux nouvelles classes CSS et SupplierPropertyLabelSupplierPropertyValue, qui ont été ajoutées à la Styles.css classe et configurées pour utiliser les mêmes paramètres de style que les ProductPropertyLabel classes CSS et ProductPropertyValue .

.ProductPropertyLabel, .SupplierPropertyLabel
{
    font-weight: bold;
    text-align: right;
}
.ProductPropertyValue, .SupplierPropertyValue
{
    padding-right: 35px;
}

Après avoir apporté ces modifications, visitez cette page via un navigateur. Comme le montre la figure 5, chaque élément DataList affiche le nom du fournisseur sous forme de texte et utilise textboxes pour afficher l’adresse, la ville et le pays/région.

Chaque fournisseur de la liste de données est modifiable

Figure 5 : Chaque fournisseur de la liste de données est modifiable (cliquer pour afficher l’image en taille réelle)

Étape 2 : Ajout d’un bouton Mettre à jour tout

Bien que chaque fournisseur de la figure 5 ait ses champs d’adresse, de ville et de pays/région affichés dans une zone de texte, aucun bouton Mettre à jour n’est actuellement disponible. Au lieu d’avoir un bouton Mettre à jour par élément, avec des DataLists entièrement modifiables, il existe généralement un seul bouton Mettre à jour tout sur la page qui, lorsqu’on clique, met à jour tous les enregistrements dans la DataList. Pour ce tutoriel, nous allons ajouter deux boutons Mettre à jour tout : l’un en haut de la page et l’autre en bas (bien que le fait de cliquer sur l’un ou l’autre bouton aura le même effet).

Commencez par ajouter un contrôle Web Button au-dessus du DataList et définissez sa ID propriété sur UpdateAll1. Ensuite, ajoutez le deuxième contrôle Web Button sous la liste de données, en affectant la valeur ID à UpdateAll2. Définissez les Text propriétés des deux boutons sur Mettre à jour tout. Enfin, créez des gestionnaires d’événements pour les deux événements Buttons Click . Au lieu de dupliquer la logique de mise à jour dans chacun des gestionnaires d’événements, refactoriser cette logique en une troisième méthode, UpdateAllSupplierAddresses, les gestionnaires d’événements appelant simplement cette troisième méthode.

protected void UpdateAll1_Click(object sender, EventArgs e)
{
    UpdateAllSupplierAddresses();
}
protected void UpdateAll2_Click(object sender, EventArgs e)
{
    UpdateAllSupplierAddresses();
}
private void UpdateAllSupplierAddresses()
{
    // TODO: Write code to update _all_ of the supplier addresses in the DataList
}

La figure 6 montre la page après l’ajout des boutons Mettre à jour tous.

Deux boutons Mettre à jour tous les boutons ont été ajoutés à la page

Figure 6 : Deux boutons de mise à jour ont été ajoutés à la page (cliquer pour afficher l’image en taille réelle)

Étape 3 : Mise à jour de toutes les informations d’adresse des fournisseurs

Avec tous les éléments de DataList qui affichent l’interface d’édition et avec l’ajout des boutons Mettre à jour tout, il ne reste plus qu’à écrire le code pour effectuer la mise à jour par lots. Plus précisément, nous devons parcourir en boucle les éléments de DataList et appeler la SuppliersBLL méthode de classe s UpdateSupplierAddress pour chacun d’eux.

La collection d’instances DataListItem qui constitue la DataList est accessible via la propriété DataList sItems. Avec une référence à un DataListItem, nous pouvons récupérer le correspondant SupplierID de la DataKeys collection et référencer par programmation les contrôles Web TextBox dans le ItemTemplate , comme l’illustre le code suivant :

private void UpdateAllSupplierAddresses()
{
    // Create an instance of the SuppliersBLL class
    SuppliersBLL suppliersAPI = new SuppliersBLL();
    // Iterate through the DataList's items
    foreach (DataListItem item in Suppliers.Items)
    {
        // Get the supplierID from the DataKeys collection
        int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]);
        // Read in the user-entered values
        TextBox address = (TextBox)item.FindControl("Address");
        TextBox city = (TextBox)item.FindControl("City");
        TextBox country = (TextBox)item.FindControl("Country");
        string addressValue = null, cityValue = null, countryValue = null;
        if (address.Text.Trim().Length > 0)
            addressValue = address.Text.Trim();
        if (city.Text.Trim().Length > 0)
              cityValue = city.Text.Trim();
        if (country.Text.Trim().Length > 0)
            countryValue = country.Text.Trim();
        // Call the SuppliersBLL class's UpdateSupplierAddress method
        suppliersAPI.UpdateSupplierAddress
            (supplierID, addressValue, cityValue, countryValue);
    }
}

Lorsque l’utilisateur clique sur l’un des boutons Mettre à jour tout, la UpdateAllSupplierAddresses méthode effectue une itération dans chacun DataListItem d’eux dans dataList Suppliers et appelle la méthode de classe SuppliersBLL s UpdateSupplierAddress , en transmettant les valeurs correspondantes. Une valeur non entrée pour les passes d’adresse, de ville ou de pays/région est une valeur de à UpdateSupplierAddress (plutôt qu’une Nothing chaîne vide), ce qui génère une base de données NULL pour les champs de l’enregistrement sous-jacent.

Notes

En guise d’amélioration, vous pouvez ajouter un status contrôle Web Label à la page qui fournit un message de confirmation après la mise à jour par lot.

Mise à jour uniquement des adresses qui ont été modifiées

L’algorithme de mise à jour par lots utilisé pour ce didacticiel appelle la UpdateSupplierAddress méthode pour chaque fournisseur dans datalist, que leurs informations d’adresse ont ou non été modifiées. Bien que ces mises à jour aveugles ne soient généralement pas un problème de performances, elles peuvent entraîner des enregistrements superflus si vous auditez les modifications apportées à la table de base de données. Par exemple, si vous utilisez des déclencheurs pour enregistrer tous les UPDATE éléments de la Suppliers table dans une table d’audit, chaque fois qu’un utilisateur clique sur le bouton Mettre à jour tout, un nouvel enregistrement d’audit est créé pour chaque fournisseur du système, que l’utilisateur ait apporté ou non des modifications.

Les classes DataTable et DataAdapter ADO.NET sont conçues pour prendre en charge les mises à jour par lots où seuls les enregistrements modifiés, supprimés et nouveaux entraînent une communication de base de données. Chaque ligne du DataTable a une RowState propriété qui indique si la ligne a été ajoutée au DataTable, si elle en a été supprimée, modifiée ou si elle reste inchangée. Lorsqu’un DataTable est initialement rempli, toutes les lignes sont marquées comme inchangées. La modification de la valeur de l’une des colonnes de ligne marque la ligne comme modifiée.

Dans la SuppliersBLL classe, nous mettons à jour les informations d’adresse du fournisseur spécifiés en lisant d’abord l’enregistrement fournisseur unique dans unSuppliersDataTable, puis nous définissons les valeurs de colonne , Cityet Country à l’aide Addressdu code suivant :

public bool UpdateSupplierAddress
    (int supplierID, string address, string city, string country)
{
    Northwind.SuppliersDataTable suppliers =
        Adapter.GetSupplierBySupplierID(supplierID);
    if (suppliers.Count == 0)
        // no matching record found, return false
        return false;
    else
    {
        Northwind.SuppliersRow supplier = suppliers[0];
        if (address == null)
            supplier.SetAddressNull();
        else
            supplier.Address = address;
        if (city == null)
            supplier.SetCityNull();
        else
            supplier.City = city;
        if (country == null)
            supplier.SetCountryNull();
        else
            supplier.Country = country;
        // Update the supplier Address-related information
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated,
        // otherwise false
        return rowsAffected == 1;
    }
}

Ce code affecte naïvement les valeurs d’adresse, de ville et de pays/région transmises au SuppliersRow dans, SuppliersDataTable que les valeurs aient ou non changé. Ces modifications entraînent la marque de la SuppliersRow propriété s RowState comme modifiée. Lorsque la méthode s Update Data Access Layer est appelée, elle constate que le SupplierRow a été modifié et envoie donc une UPDATE commande à la base de données.

Imaginez, toutefois, que nous ajoutions du code à cette méthode pour affecter uniquement les valeurs d’adresse, de ville et de pays/région transmises si elles diffèrent des SuppliersRow valeurs existantes. Dans le cas où l’adresse, la ville et le pays/région sont identiques aux données existantes, aucune modification n’est apportée et les SupplierRow s RowState restent marqués comme inchangés. Le résultat net est que lorsque la méthode DAL est appelée, aucun appel de base de données n’est Update effectué, car le SuppliersRow n’a pas été modifié.

Pour appliquer cette modification, remplacez les instructions qui attribuent aveuglément les valeurs d’adresse transmise, de ville et de pays/région par le code suivant :

// Only assign the values to the SupplierRow's column values if they differ
if (address == null && !supplier.IsAddressNull())
    supplier.SetAddressNull();
else if ((address != null && supplier.IsAddressNull()) ||
         (!supplier.IsAddressNull() &&
         string.Compare(supplier.Address, address) != 0))
    supplier.Address = address;
if (city == null && !supplier.IsCityNull())
    supplier.SetCityNull();
else if ((city != null && supplier.IsCityNull()) ||
         (!supplier.IsCityNull() && string.Compare(supplier.City, city) != 0))
    supplier.City = city;
if (country == null && !supplier.IsCountryNull())
    supplier.SetCountryNull();
else if ((country != null && supplier.IsCountryNull()) ||
         (!supplier.IsCountryNull() &&
         string.Compare(supplier.Country, country) != 0))
    supplier.Country = country;

Avec ce code ajouté, la méthode DAL s Update envoie une UPDATE instruction à la base de données uniquement pour les enregistrements dont les valeurs liées à l’adresse ont changé.

Nous pouvons également vérifier s’il existe des différences entre les champs d’adresse transmise et les données de base de données et, s’il n’y en a pas, ignorer simplement l’appel à la méthode dal s Update . Cette approche fonctionne bien si vous utilisez la méthode directe de base de données, car la méthode directe de base de données n’est pas transmise à un SuppliersRow instance dont RowState vous pouvez vérifier si un appel de base de données est réellement nécessaire.

Notes

Chaque fois que la UpdateSupplierAddress méthode est appelée, un appel est effectué à la base de données pour récupérer des informations sur l’enregistrement mis à jour. Ensuite, s’il y a des modifications dans les données, un autre appel à la base de données est effectué pour mettre à jour la ligne de table. Ce flux de travail peut être optimisé en créant une UpdateSupplierAddress surcharge de méthode qui accepte une EmployeesDataTable instance contenant toutes les modifications de la BatchUpdate.aspx page. Ensuite, il peut effectuer un appel à la base de données pour obtenir tous les enregistrements de la Suppliers table. Les deux jeux de résultats peuvent ensuite être énumérés et seuls les enregistrements où des modifications ont été apportées peuvent être mis à jour.

Résumé

Dans ce tutoriel, nous avons vu comment créer une datalist entièrement modifiable, ce qui permet à un utilisateur de modifier rapidement les informations d’adresse de plusieurs fournisseurs. Nous avons commencé par définir l’interface de modification d’un contrôle Web TextBox pour les valeurs d’adresse, de ville et de pays/région du fournisseur dans dataList s ItemTemplate. Ensuite, nous avons ajouté les boutons Mettre à jour tout au-dessus et au-dessous de la liste de données. Une fois qu’un utilisateur a apporté ses modifications et cliqué sur l’un des boutons Mettre à jour tout, les DataListItem s sont énumérés et un appel à la SuppliersBLL méthode class s UpdateSupplierAddress est effectué.

Bonne programmation !

À propos de l’auteur

Scott Mitchell, auteur de sept livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Il est accessible à l’adressemitchell@4GuysFromRolla.com . ou via son blog, qui se trouve à l’adresse http://ScottOnWriting.NET.

Remerciements spéciaux à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Zack Jones et Ken Pespisa ont été les principaux réviseurs de ce tutoriel. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.