Partager via


Réalisation de mises à jour par lots (VB)

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 de l’élément. Comme le GridView modifiable standard, chaque élément de la Liste de données incluait un bouton Modifier qui, lorsqu’il est cliqué, 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 de cas d’usage obligent l’utilisateur à modifier de nombreux enregistrements. Si un utilisateur doit modifier des dizaines d’enregistrements et qu’il est obligé de cliquer sur Modifier, d’apporter ses 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, une 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 de taille complète)

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

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

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

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

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

Pour un DataList entièrement modifiable, nous voulons que tous les DataListItem s soient rendus à l’aide de l’interface modifiable. La façon la plus simple d’y parvenir consiste à définir l’interface modifiable dans le 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é Supplierssur . À partir de la balise active 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 (cliquez pour afficher l’image de taille complète)

Configurez ObjectDataSource pour récupérer des données à l’aide de la SuppliersBLL méthode de GetSuppliers() classe (voir la figure 3). Comme avec le didacticiel 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) sous l’onglet UPDATE (voir la figure 4).

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

Figure 3 : Récupérer des informations sur le fournisseur à l’aide de la méthode (Cliquez pour afficher l’image GetSuppliers()de taille complète)

Définir la liste déroulante sur (Aucun) dans l’onglet UPDATE

Figure 4 : Définir la liste déroulante sur (Aucun) dans l’onglet UPDATE (Cliquez pour afficher l’image de taille complète)

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

Prenez un moment pour créer une interface d’édition 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>

Remarque

Comme avec le didacticiel précédent, dataList de ce didacticiel doit avoir son état d’affichage activé.

Dans l’I ItemTemplate m’utilise deux nouvelles classes CSS, SupplierPropertyLabel et SupplierPropertyValue, 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.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 la région/pays.

Chaque fournisseur dans DataList est modifiable

Figure 5 : Chaque fournisseur de la Liste de données est modifiable (cliquez pour afficher l’image de taille complète)

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

Bien que chaque fournisseur de la figure 5 ait son adresse, sa ville et ses champs pays/région affichés dans une zone de texte, il n’existe actuellement aucun bouton Mettre à jour. 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 tous sur la page qui, lorsque vous cliquez, met à jour tous les enregistrements dans DataList. Pour ce tutoriel, nous allons ajouter deux boutons Mettre à jour tous : un en haut de la page et un en bas (bien que cliquer sur l’un ou l’autre bouton aura le même effet).

Commencez par ajouter un contrôle Web Button au-dessus de DataList et définissez sa ID propriété sur UpdateAll1. Ensuite, ajoutez le deuxième contrôle Web Button sous DataList, en définissant sa valeur ID UpdateAll2sur . 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, refactorisons cette logique à une troisième méthode, UpdateAllSupplierAddressesce qui permet aux gestionnaires d’événements d’appeler simplement cette troisième méthode.

Protected Sub UpdateAll1_Click(sender As Object, e As EventArgs) _
    Handles UpdateAll1.Click
    UpdateAllSupplierAddresses()
End Sub
Protected Sub UpdateAll2_Click(sender As Object, e As EventArgs) _
    Handles UpdateAll2.Click
    UpdateAllSupplierAddresses()
End Sub
Private Sub UpdateAllSupplierAddresses()
    ' TODO: Write code to update _all_ of the supplier addresses in the DataList
End Sub

La figure 6 montre la page une fois que les boutons Mettre à jour tous ont été ajoutés.

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

Figure 6 : Deux boutons mettre à jour tous les boutons ont été ajoutés à la page (cliquez pour afficher l’image de taille complète)

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

Avec tous les éléments de DataList affichant l’interface d’édition et avec l’ajout des boutons Mettre à jour tous, tout ce qui reste écrit le code pour effectuer la mise à jour par lots. Plus précisément, nous devons parcourir les éléments de DataList et appeler la SuppliersBLL méthode de UpdateSupplierAddress classe pour chacune d’elles.

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

Private Sub UpdateAllSupplierAddresses()
    ' Create an instance of the SuppliersBLL class
    Dim suppliersAPI As New SuppliersBLL()
    ' Iterate through the DataList's items
    For Each item As DataListItem In Suppliers.Items
        ' Get the supplierID from the DataKeys collection
        Dim supplierID As Integer = Convert.ToInt32(Suppliers.DataKeys(item.ItemIndex))
        ' Read in the user-entered values
        Dim address As TextBox = CType(item.FindControl("Address"), TextBox)
        Dim city As TextBox = CType(item.FindControl("City"), TextBox)
        Dim country As TextBox = CType(item.FindControl("Country"), TextBox)
        Dim addressValue As String = Nothing, _
            cityValue As String = Nothing, _
            countryValue As String = Nothing
        If address.Text.Trim().Length > 0 Then
            addressValue = address.Text.Trim()
        End If
        If city.Text.Trim().Length > 0 Then
            cityValue = city.Text.Trim()
        End If
        If country.Text.Trim().Length > 0 Then
            countryValue = country.Text.Trim()
        End If
        ' Call the SuppliersBLL class's UpdateSupplierAddress method
        suppliersAPI.UpdateSupplierAddress _
            (supplierID, addressValue, cityValue, countryValue)
    Next
End Sub

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

Remarque

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

Mise à jour uniquement de ces 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 soient modifiées ou non. 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 éléments UPDATE 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é 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 toute communication de base de données. Chaque ligne du DataTable a une RowState propriété qui indique si la ligne a été ajoutée à DataTable, supprimée de celle-ci, modifiée ou 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é en lisant d’abord dans l’enregistrement du fournisseur unique en un SuppliersDataTable , puis en définissant les Addressvaleurs , Cityet Country les valeurs de colonne à l’aide du code suivant :

Public Function UpdateSupplierAddress _
    (supplierID As Integer, address As String, city As String, country As String) _
    As Boolean
    Dim suppliers As Northwind.SuppliersDataTable = _
        Adapter.GetSupplierBySupplierID(supplierID)
    If suppliers.Count = 0 Then
        ' no matching record found, return false
        Return False
    Else
        Dim supplier As Northwind.SuppliersRow = suppliers(0)
        If address Is Nothing Then
            supplier.SetAddressNull()
        Else
            supplier.Address = address
        End If
        If city Is Nothing Then
            supplier.SetCityNull()
        Else
            supplier.City = city
        End If
        If country Is Nothing Then
            supplier.SetCountryNull()
        Else
            supplier.Country = country
        End If
        ' Update the supplier Address-related information
        Dim rowsAffected As Integer = Adapter.Update(supplier)
        ' Return true if precisely one row was updated, otherwise false
        Return rowsAffected = 1
    End If
End Function

Ce code affecte naivement l’adresse passée, la ville et les valeurs pays/région à l’emplacement SuppliersRow SuppliersDataTable ou non, que les valeurs aient changé ou non. Ces modifications entraînent la marque de la SuppliersRow propriété s RowState comme modifiée. Lorsque la méthode de Update couche d’accès aux données est appelée, elle voit que le fichier SupplierRow a été modifié et envoie donc une UPDATE commande à la base de données.

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

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

' Only assign the values to the SupplierRow's column values if they differ
If address Is Nothing AndAlso Not supplier.IsAddressNull() Then
    supplier.SetAddressNull()
ElseIf (address IsNot Nothing AndAlso supplier.IsAddressNull) _
    OrElse (Not supplier.IsAddressNull() AndAlso _
                String.Compare(supplier.Address, address) <> 0) Then
    supplier.Address = address
End If
If city Is Nothing AndAlso Not supplier.IsCityNull() Then
    supplier.SetCityNull()
ElseIf (city IsNot Nothing AndAlso supplier.IsCityNull) _
    OrElse (Not supplier.IsCityNull() AndAlso _
                String.Compare(supplier.City, city) <> 0) Then
    supplier.City = city
End If
If country Is Nothing AndAlso Not supplier.IsCountryNull() Then
    supplier.SetCountryNull()
ElseIf (country IsNot Nothing AndAlso supplier.IsCountryNull) _
    OrElse (Not supplier.IsCountryNull() AndAlso _
                String.Compare(supplier.Country, country) <> 0) Then
    supplier.Country = country
End If

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

Sinon, nous pourrions suivre si des différences existent entre les champs d’adresse transmis et les données de base de données et, s’il n’y en a pas, il suffit de contourner l’appel à la méthode DAL.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 passée à une SuppliersRow instance dont RowState vous pouvez vérifier si un appel de base de données est réellement nécessaire.

Remarque

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 existe 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 qui a 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 ensembles de résultats peuvent ensuite être énumérés et seuls les enregistrements où des modifications se sont produites 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 un contrôle Web TextBox pour les valeurs d’adresse, de ville et de région du fournisseur dans dataList s ItemTemplate. Ensuite, nous avons ajouté les boutons Mettre à jour tous les boutons ci-dessus et en 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 tous, les DataListItem s sont énumérés et un appel à la SuppliersBLL méthode s de UpdateSupplierAddress classe 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 en tant que consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 en 24 heures. Il peut être accessible à mitchell@4GuysFromRolla.com. ou via son blog, qui peut être trouvé à http://ScottOnWriting.NET.

Merci spécial à

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