Partager via


Mise à jour par lots (VB)

par Scott Mitchell

Télécharger le PDF

Découvrez comment mettre à jour plusieurs enregistrements de base de données dans une seule opération. Dans la couche Interface utilisateur, nous créons un GridView où chaque ligne est modifiable. Dans la couche d’accès aux données, nous encapsulons les opérations de mise à jour multiples au sein d’une transaction pour vous assurer que toutes les mises à jour réussissent ou que toutes les mises à jour sont restaurées.

Introduction

Dans le tutoriel précédent, nous avons vu comment étendre la couche d’accès aux données afin d’ajouter la prise en charge des transactions de base de données. Les transactions de base de données garantissent qu’une série d’instructions de modification de données sera traitée comme une opération atomique, ce qui garantit que toutes les modifications échouent ou que toutes les modifications réussissent. Grâce à cette fonctionnalité DAL de bas niveau, nous sommes prêts à attirer l’attention sur la création d’interfaces de modification de données par lots.

Dans ce tutoriel, nous allons générer un GridView dans lequel chaque ligne est modifiable (voir la figure 1). Étant donné que chaque ligne est affichée dans son interface d’édition, il n’est pas nécessaire d’utiliser une colonne de boutons Modifier, Mettre à jour et Annuler. Au lieu de cela, il existe deux boutons Mettre à jour les produits sur la page qui, lorsqu’ils cliquent, énumèrent les lignes GridView et mettent à jour la base de données.

Chaque ligne dans GridView est modifiable

Figure 1 : Chaque ligne dans GridView est modifiable (cliquez pour afficher l’image de taille complète)

Commençons !

Remarque

Dans le didacticiel Exécution des mises à jour batch, nous avons créé une interface de modification par lots à l’aide du contrôle DataList. Ce tutoriel diffère de celui précédent dans lequel il utilise un GridView et la mise à jour par lots est effectuée dans l’étendue d’une transaction. Après avoir terminé ce tutoriel, je vous encourage à revenir au didacticiel précédent et à le mettre à jour pour utiliser la fonctionnalité liée aux transactions de base de données ajoutée dans le didacticiel précédent.

Examen des étapes de modification de toutes les lignes GridView

Comme indiqué dans le didacticiel Vue d’ensemble de l’insertion, de la mise à jour et de la suppression des données, GridView offre une prise en charge intégrée de la modification de ses données sous-jacentes par ligne. En interne, GridView note la ligne modifiable par le biais de sa EditIndex propriété. Comme GridView est lié à sa source de données, il vérifie chaque ligne pour voir si l’index de la ligne est égal à la valeur de EditIndex. Si c’est le cas, ces champs de ligne sont rendus à l’aide de leurs interfaces de modification. Pour BoundFields, l’interface d’édition est un TextBox dont Text la propriété est affectée à la valeur du champ de données spécifié par la propriété BoundField.DataField Pour TemplateFields, il EditItemTemplate est utilisé à la ItemTemplateplace du .

Rappelez-vous que le flux de travail d’édition démarre lorsqu’un utilisateur clique sur un bouton Modifier d’une ligne. Cela provoque une publication différée, définit la propriété gridView EditIndex sur l’index de ligne cliqué et rebine les données à la grille. Lorsqu’un bouton Annuler d’une ligne est cliqué, sur la publication, la EditIndex valeur est définie avant de -1 rebiner les données à la grille. Étant donné que les lignes de GridView commencent à indexer à zéro, la définition EditIndex de la valeur a -1 pour effet d’afficher GridView en mode lecture seule.

La propriété fonctionne bien pour la EditIndex modification par ligne, mais n’est pas conçue pour la modification par lot. Pour rendre l’intégralité de GridView modifiable, nous devons avoir chaque rendu de ligne à l’aide de son interface d’édition. Le moyen le plus simple d’y parvenir consiste à créer où chaque champ modifiable est implémenté en tant que TemplateField avec son interface d’édition définie dans le ItemTemplate.

Au cours des étapes suivantes, nous allons créer un GridView entièrement modifiable. À l’étape 1, nous allons commencer par créer GridView et objectDataSource et convertir ses BoundFields et CheckBoxField en TemplateFields. Dans les étapes 2 et 3, nous allons déplacer les interfaces d’édition de TemplateFields EditItemTemplate vers leur ItemTemplate s.

Étape 1 : affichage des informations sur le produit

Avant de nous soucier de la création d’un GridView où sont modifiables les lignes, commençons par afficher simplement les informations sur le produit. Ouvrez la BatchUpdate.aspx page dans le BatchData dossier et faites glisser un GridView à partir de la boîte à outils sur le Concepteur. Définissez gridView s ID sur ProductsGrid et, à partir de sa balise active, choisissez de le lier à un nouvel ObjectDataSource nommé ProductsDataSource. Configurez ObjectDataSource pour récupérer ses données à partir de la ProductsBLL méthode de GetProducts classe.

Configurer ObjectDataSource pour utiliser la classe ProductsBLL

Figure 2 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image ProductsBLLde taille complète)

Récupérer les données de produit à l’aide de la méthode GetProducts

Figure 3 : Récupérer les données de produit à l’aide de la GetProducts méthode (Cliquez pour afficher l’image de taille complète)

Comme GridView, les fonctionnalités de modification d’ObjectDataSource sont conçues pour fonctionner sur une base par ligne. Pour mettre à jour un ensemble d’enregistrements, nous devons écrire un peu de code dans la classe code-behind de la page ASP.NET qui lote les données et les transmet à la BLL. Par conséquent, définissez les listes déroulantes dans les onglets UPDATE, INSERT et DELETE de ObjectDataSource sur (Aucun). Cliquez sur Terminer pour terminer l’Assistant.

Définir les listes déroulantes dans les onglets UPDATE, INSERT et DELETE sur (Aucun)

Figure 4 : Définir les listes déroulantes dans les onglets UPDATE, INSERT et DELETE sur (Aucun) (Cliquez pour afficher l’image de taille complète)

Une fois l’Assistant Configuration de la source de données terminée, le balisage déclaratif objectDataSource doit ressembler à ce qui suit :

<asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

L’exécution de l’Assistant Configurer la source de données entraîne également la création de Visual Studio BoundFields et d’un CheckBoxField pour les champs de données de produit dans GridView. Pour ce tutoriel, laissez l’utilisateur uniquement afficher et modifier le nom, la catégorie, le prix et l’état du produit supprimé. Supprimez tous, mais les ProductNamechamps, CategoryNameUnitPriceet Discontinued renommez les HeaderText propriétés des trois premiers champs en Product, Category et Price, respectivement. Enfin, cochez les cases Activer la pagination et activer le tri dans la balise active gridView.

À ce stade, GridView a trois BoundFields (ProductName, CategoryNameet UnitPrice) et un CheckBoxField (Discontinued). Nous devons convertir ces quatre champs en TemplateFields, puis déplacer l’interface d’édition du TemplateField vers EditItemTemplate son ItemTemplate.

Remarque

Nous avons exploré la création et la personnalisation de TemplateFields dans le didacticiel Personnalisation de l’interface de modification de données. Nous allons parcourir les étapes de conversion des BoundFields et CheckBoxField en TemplateFields et définir leurs interfaces d’édition dans leurs ItemTemplate s, mais si vous êtes bloqué ou besoin d’un actualisation, n’hésitez pas à vous reporter à ce didacticiel précédent.

À partir de la balise active gridView, cliquez sur le lien Modifier les colonnes pour ouvrir la boîte de dialogue Champs. Ensuite, sélectionnez chaque champ et cliquez sur le champ Convertir ce champ en lien TemplateField.

Convertir les boundFields existants et CheckBoxField en TemplateFields

Figure 5 : Convertir les champs BoundField existants et CheckBoxField en templateFields

Maintenant que chaque champ est un TemplateField, nous sommes prêts à déplacer l’interface d’édition du EditItemTemplate s vers le ItemTemplate s.

Étape 2 : CréationProductName des interfaces,UnitPrice etDiscontinuedmodification

La création des ProductNameinterfaces , UnitPriceet Discontinued la modification sont la rubrique de cette étape et sont assez simples, car chaque interface est déjà définie dans templateField s EditItemTemplate. La création de l’interface CategoryName d’édition est un peu plus impliquée, car nous devons créer une liste déroulante des catégories applicables. Cette CategoryName interface d’édition est traitée à l’étape 3.

Commençons par TemplateField ProductName . Cliquez sur le lien Modifier les modèles à partir de la balise active gridView, puis accédez à TemplateField ProductName s EditItemTemplate. Sélectionnez la Zone de texte, copiez-la dans le Presse-papiers, puis collez-la dans le ProductName TemplateField s ItemTemplate. Remplacez la propriété ProductNamede TextBox ID par .

Ensuite, ajoutez un RequiredFieldValidator pour ItemTemplate vous assurer que l’utilisateur fournit une valeur pour chaque nom de produit. Définissez la ControlToValidate propriété sur ProductName, la ErrorMessage propriété sur Vous devez fournir le nom du produit. et la Text propriété à *. Après avoir effectué ces ajouts à l’écran ItemTemplate, votre écran doit ressembler à la figure 6.

ProductName TemplateField inclut désormais une zone de texte et un RequiredFieldValidator

Figure 6 : TemplateField ProductName inclut désormais une zone de texte et un RequiredFieldValidator (cliquez pour afficher l’image de taille complète)

Pour l’interface d’édition UnitPrice , commencez par copier la zone de texte de la EditItemTemplate zone de texte vers le ItemTemplate. Ensuite, placez un $ devant textBox et définissez sa ID propriété sur UnitPrice et sa Columns propriété sur 8 .

Ajoutez également un CompareValidator aux UnitPrice s ItemTemplate pour vous assurer que la valeur entrée par l’utilisateur est une valeur monétaire valide supérieure ou égale à 0,00 $. Définissez la propriété du ControlToValidate validateur sur UnitPrice, sa ErrorMessage propriété sur Vous devez entrer une valeur monétaire valide. Veuillez omettre tous les symboles monétaires., sa Text propriété à *, sa Type propriété à Currency, sa Operator propriété à GreaterThanEqual, et sa ValueToCompare propriété à 0 .

Ajouter un CompareValidator pour vérifier que le prix entré est une valeur monétaire non négative

Figure 7 : Ajouter un CompareValidator pour vérifier que le prix entré est une valeur monétaire non négative (cliquez pour afficher l’image de taille complète)

Pour templateField Discontinued , vous pouvez utiliser checkBox déjà défini dans le ItemTemplate. Définissez simplement sa ID valeur sur Discontinued et sa Enabled propriété sur True.

Étape 3 : Création de l’interface d’éditionCategoryName

L’interface d’édition de CategoryName TemplateField contient EditItemTemplate un TextBox qui affiche la valeur du CategoryName champ de données. Nous devons remplacer cela par un DropDownList qui répertorie les catégories possibles.

Remarque

Le didacticiel Personnalisation de l’interface de modification de données contient une discussion plus approfondie et complète sur la personnalisation d’un modèle pour inclure une liste déroulante, par opposition à une zone de texte. Pendant que les étapes ici sont terminées, elles sont présentées tersely. Pour plus d’informations sur la création et la configuration des catégories DropDownList, reportez-vous au didacticiel Personnalisation de l’interface de modification des données.

Faites glisser un DropDownList de la boîte à outils vers templateField CategoryName s ItemTemplate, en définissant sa valeur ID Categoriessur . À ce stade, nous allons généralement définir la source de données de DropDownLists par le biais de sa balise active, en créant un ObjetDataSource. Toutefois, cela ajoute ObjectDataSource au sein de l’instance ItemTemplateObjectDataSource, ce qui entraîne la création d’une instance ObjectDataSource pour chaque ligne GridView. Au lieu de cela, nous allons créer l’ObjectDataSource en dehors des TemplateFields de GridView. Terminez la modification du modèle et faites glisser un ObjectDataSource à partir de la boîte à outils vers le Concepteur sous ProductsDataSource ObjectDataSource. Nommez le nouvel ObjectDataSource CategoriesDataSource et configurez-le pour utiliser la CategoriesBLL méthode de GetCategories classe.

Configurer ObjectDataSource pour utiliser la classe CategoriesBLL

Figure 8 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image CategoriesBLLde taille complète)

Récupérer les données de catégorie à l’aide de la méthode GetCategories

Figure 9 : Récupérer les données de catégorie à l’aide de la GetCategories méthode (Cliquez pour afficher l’image de taille complète)

Étant donné que cette ObjectDataSource est utilisée simplement pour récupérer des données, définissez les listes déroulantes dans les onglets UPDATE et DELETE sur (Aucun). Cliquez sur Terminer pour terminer l’Assistant.

Définir les listes déroulantes dans les onglets UPDATE et DELETE sur (Aucun)

Figure 10 : Définir les listes déroulantes dans les onglets UPDATE et DELETE sur (Aucun) (Cliquez pour afficher l’image de taille complète)

Une fois l’Assistant terminé, le CategoriesDataSource balisage déclaratif doit ressembler à ce qui suit :

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

Avec la création et la CategoriesDataSource configuration, revenez à TemplateField s ItemTemplate et, à CategoryName partir de la balise active DropDownList, cliquez sur le lien Choisir une source de données. Dans l’Assistant Configuration de source de données, sélectionnez l’option CategoriesDataSource dans la première liste déroulante et choisissez d’avoir CategoryName été utilisée pour l’affichage et CategoryID comme valeur.

Lier la liste déroulante à CategoriesDataSource

Figure 11 : Lier la liste déroulante à la CategoriesDataSource liste déroulante (cliquez pour afficher l’image de taille complète)

À ce stade, la Categories Liste déroulante répertorie toutes les catégories, mais elle ne sélectionne pas encore automatiquement la catégorie appropriée pour le produit lié à la ligne GridView. Pour ce faire, nous devons définir les Categories dropDownList sur SelectedValue la valeur du CategoryID produit. Cliquez sur le lien Modifier dataBindings à partir de la balise active de DropDownList et associez la SelectedValue propriété au champ de données, comme illustré dans la CategoryID figure 12.

Lier la valeur CategoryID du produit à la propriété SelectedValue de DropDownList

Figure 12 : Lier la valeur du CategoryID produit à la propriété DropDownList SelectedValue

Un dernier problème reste : si le produit n’a pas de CategoryID valeur spécifiée, l’instruction de liaison de données sur SelectedValue aboutira à une exception. Cela est dû au fait que dropDownList contient uniquement des éléments pour les catégories et n’offre pas d’option pour ces produits qui ont une NULL valeur de base de données pour CategoryID. Pour résoudre ce problème, définissez la propriété DropDownList AppendDataBoundItems sur True et ajoutez un nouvel élément à dropDownList, en omettant la Value propriété de la syntaxe déclarative. Autrement dit, assurez-vous que la Categories syntaxe déclarative de DropDownList ressemble à ce qui suit :

<asp:DropDownList ID="Categories" runat="server" AppendDataBoundItems="True" 
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName" 
    DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'>
    <asp:ListItem Value=">-- Select One --</asp:ListItem>
</asp:DropDownList>

Notez comment l’attribut <asp:ListItem Value=""> -- Select One - a explicitement défini sur Value une chaîne vide. Reportez-vous au didacticiel Personnalisation de l’interface de modification des données pour une discussion plus approfondie sur la raison pour laquelle cet élément DropDownList supplémentaire est nécessaire pour gérer le NULL cas et pourquoi l’affectation de la Value propriété à une chaîne vide est essentielle.

Remarque

Il existe ici un problème potentiel de performances et d’extensibilité qui vaut la peine d’être mentionné. Étant donné que chaque ligne a un DropDownList qui utilise la CategoriesDataSource source de données comme source de données, la CategoriesBLL méthode s de GetCategories la classe est appelée n fois par visite de page, où n correspond au nombre de lignes dans GridView. Ces n appels pour GetCategories générer n requêtes vers la base de données. Cet impact sur la base de données peut être réduit en mettant en cache les catégories retournées dans un cache par requête ou via la couche de mise en cache à l’aide d’une dépendance de mise en cache SQL ou d’une expiration très courte en fonction du temps.

Étape 4 : Fin de l’interface d’édition

Nous avons apporté un certain nombre de modifications aux modèles GridView sans interrompre pour afficher notre progression. Prenez un moment pour voir notre progression via un navigateur. Comme le montre la figure 13, chaque ligne est rendue à l’aide de son ItemTemplate, qui contient l’interface d’édition de cellule.

Chaque ligne GridView est modifiable

Figure 13 : Chaque ligne GridView est modifiable (cliquez pour afficher l’image de taille complète)

Il existe quelques problèmes mineurs de mise en forme dont nous devrions nous occuper à ce stade. Tout d’abord, notez que la UnitPrice valeur contient quatre décimales. Pour résoudre ce problème, revenez à TemplateField s ItemTemplate et, à UnitPrice partir de la balise active de TextBox, cliquez sur le lien Modifier dataBindings. Ensuite, spécifiez que la Text propriété doit être mise en forme sous forme de nombre.

Mettre en forme la propriété Text en tant que nombre

Figure 14 : Mettre en forme la Text propriété en tant que nombre

Deuxièmement, laissez centrer la case à cocher dans la Discontinued colonne (plutôt que de l’aligner à gauche). Cliquez sur Modifier les colonnes à partir de la balise active gridView, puis sélectionnez TemplateField Discontinued dans la liste des champs dans le coin inférieur gauche. Explorez et définissez ItemStyle la propriété sur Center, comme illustré dans la HorizontalAlign figure 15.

Centrer la CheckBox abandonnée

Figure 15 : Centrer le Discontinued CheckBox

Ensuite, ajoutez un contrôle ValidationSummary à la page et définissez sa ShowMessageBox propriété sur True et sa ShowSummary propriété Falsesur . Ajoutez également les contrôles Web Button qui, lorsqu’ils sont cliqués, mettent à jour les modifications de l’utilisateur. Plus précisément, ajoutez deux contrôles Web Button, un au-dessus de GridView et un en dessous, en définissant les deux propriétés des contrôles Text sur Update Products .

Étant donné que l’interface d’édition de GridView est définie dans ses ModèlesFields s, les EditItemTemplate s sont superflus ItemTemplate et peuvent être supprimés.

Après avoir apporté les modifications de mise en forme mentionnées ci-dessus, l’ajout des contrôles Button et la suppression des s inutiles EditItemTemplate , la syntaxe déclarative de votre page doit ressembler à ce qui suit :

<p>
    <asp:Button ID="UpdateAllProducts1" runat="server" Text="Update Products" />
</p>
<p>
    <asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
        AllowPaging="True" AllowSorting="True">
        <Columns>
            <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
                <ItemTemplate>
                    <asp:TextBox ID="ProductName" runat="server" 
                        Text='<%# Bind("ProductName") %>'></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
                        ControlToValidate="ProductName"
                        ErrorMessage="You must provide the product's name." 
                        runat="server">*</asp:RequiredFieldValidator>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Category" 
                SortExpression="CategoryName">
                <ItemTemplate>
                    <asp:DropDownList ID="Categories" runat="server" 
                        AppendDataBoundItems="True" 
                        DataSourceID="CategoriesDataSource"
                        DataTextField="CategoryName" 
                        DataValueField="CategoryID" 
                        SelectedValue='<%# Bind("CategoryID") %>'>
                        <asp:ListItem>-- Select One --</asp:ListItem>
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Price" 
                SortExpression="UnitPrice">
                <ItemTemplate>
                    $<asp:TextBox ID="UnitPrice" runat="server" Columns="8" 
                        Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>
                    <asp:CompareValidator ID="CompareValidator1" runat="server" 
                        ControlToValidate="UnitPrice"
                        ErrorMessage="You must enter a valid currency value. 
                                      Please omit any currency symbols."
                        Operator="GreaterThanEqual" Type="Currency" 
                        ValueToCompare="0">*</asp:CompareValidator>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
                <ItemTemplate>
                    <asp:CheckBox ID="Discontinued" runat="server" 
                        Checked='<%# Bind("Discontinued") %>' />
                </ItemTemplate>
                <ItemStyle HorizontalAlign="Center" />
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</p>
<p>
    <asp:Button ID="UpdateAllProducts2" runat="server" Text="Update Products" />
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetProducts" TypeName="ProductsBLL">
    </asp:ObjectDataSource>
    <asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetCategories" TypeName="CategoriesBLL">
    </asp:ObjectDataSource>
    <asp:ValidationSummary ID="ValidationSummary1" runat="server" 
        ShowMessageBox="True" ShowSummary="False" />
</p>

La figure 16 montre cette page lorsqu’elle est consultée par le biais d’un navigateur une fois que les contrôles Web Button ont été ajoutés et que les modifications de mise en forme ont été apportées.

La page comprend maintenant deux boutons mettre à jour les produits

Figure 16 : La page inclut désormais deux boutons Mettre à jour les produits (cliquez pour afficher l’image de taille complète)

Étape 5 : Mise à jour des produits

Lorsqu’un utilisateur visite cette page, il effectue ses modifications, puis clique sur l’un des deux boutons Mettre à jour les produits. À ce stade, nous devons enregistrer les valeurs entrées par l’utilisateur pour chaque ligne dans une ProductsDataTable instance, puis passer cela à une méthode BLL qui transmettra ensuite cette ProductsDataTable instance à la méthode DAL UpdateWithTransaction . La UpdateWithTransaction méthode que nous avons créée dans le tutoriel précédent garantit que le lot de modifications sera mis à jour en tant qu’opération atomique.

Créez une méthode nommée BatchUpdate dans BatchUpdate.aspx.vb et ajoutez le code suivant :

Private Sub BatchUpdate()
    ' Enumerate the GridView's Rows collection and create a ProductRow
    Dim productsAPI As New ProductsBLL()
    Dim products As Northwind.ProductsDataTable = productsAPI.GetProducts()
    For Each gvRow As GridViewRow In ProductsGrid.Rows
        ' Find the ProductsRow instance in products that maps to gvRow
        Dim productID As Integer = _
            Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
        Dim product As Northwind.ProductsRow = products.FindByProductID(productID)
        If product IsNot Nothing Then
            ' Programmatically access the form field elements in the 
            ' current GridViewRow
            Dim productName As TextBox = _
                CType(gvRow.FindControl("ProductName"), TextBox)
            Dim categories As DropDownList = _
                CType(gvRow.FindControl("Categories"), DropDownList)
            Dim unitPrice As TextBox = _
                CType(gvRow.FindControl("UnitPrice"), TextBox)
            Dim discontinued As CheckBox = _
                CType(gvRow.FindControl("Discontinued"), CheckBox)
            ' Assign the user-entered values to the current ProductRow
            product.ProductName = productName.Text.Trim()
            If categories.SelectedIndex = 0 Then 
                product.SetCategoryIDNull() 
            Else 
                product.CategoryID = Convert.ToInt32(categories.SelectedValue)
            End If
            If unitPrice.Text.Trim().Length = 0 Then 
                product.SetUnitPriceNull() 
            Else 
                product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
            End If
            product.Discontinued = discontinued.Checked
        End If
    Next
    ' Now have the BLL update the products data using a transaction
    productsAPI.UpdateWithTransaction(products)
End Sub

Cette méthode commence par récupérer tous les produits dans un ProductsDataTable appel à la méthode BLL.GetProducts Il énumère ensuite la ProductGrid collection GridViewRows. La Rows collection contient une GridViewRow instance pour chaque ligne affichée dans GridView. Étant donné que nous affichons au maximum dix lignes par page, la collection gridView Rows n’aura pas plus de dix éléments.

Pour chaque ligne, l’élément ProductID est saisi à partir de la DataKeys collection et le approprié ProductsRow est sélectionné à partir du ProductsDataTable. Les quatre contrôles d’entrée TemplateField sont référencés par programmation et leurs valeurs affectées aux propriétés de l’instance ProductsRow . Une fois que chaque valeur de ligne GridView a été utilisée pour mettre à jour, ProductsDataTableelle est passée à la méthode BLL s UpdateWithTransaction qui, comme nous l’avons vu dans le tutoriel précédent, appelle simplement vers le bas dans la méthode DAL.UpdateWithTransaction

L’algorithme de mise à jour par lots utilisé pour ce didacticiel met à jour chaque ligne dans celle ProductsDataTable qui correspond à une ligne dans GridView, que les informations du produit 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. De retour dans le didacticiel Exécution des mises à jour par lots, nous avons exploré une interface de mise à jour par lots avec DataList et ajouté du code qui ne mettre à jour que les enregistrements qui ont été réellement modifiés par l’utilisateur. N’hésitez pas à utiliser les techniques d’exécution des mises à jour batch pour mettre à jour le code dans ce didacticiel, si vous le souhaitez.

Remarque

Lors de la liaison de la source de données à GridView via sa balise active, Visual Studio affecte automatiquement la ou les valeurs de clé primaire de la source de données à la propriété GridView DataKeyNames . Si vous n’avez pas lié ObjectDataSource à GridView via la balise active gridView comme indiqué à l’étape 1, vous devez définir manuellement la propriété GridView sur DataKeyNames ProductID pour accéder à la ProductID valeur de chaque ligne via la DataKeys collection.

Le code utilisé dans BatchUpdate est similaire à celui utilisé dans les méthodes BLL UpdateProduct , la principale différence étant que dans les UpdateProduct méthodes, une seule ProductRow instance est récupérée à partir de l’architecture. Le code qui attribue les propriétés du code ProductRow est le même entre les UpdateProducts méthodes et le code dans la For Each boucle BatchUpdate, comme c’est le modèle global.

Pour suivre ce tutoriel, nous devons appeler la BatchUpdate méthode lorsque l’un des boutons Mettre à jour les produits est cliqué. Créez des gestionnaires d’événements pour les Click événements de ces deux contrôles Button et ajoutez le code suivant dans les gestionnaires d’événements :

BatchUpdate()
ClientScript.RegisterStartupScript(Me.GetType(), "message", _
    "alert('The products have been updated.');", True)

Tout d’abord, un appel est effectué à BatchUpdate. Ensuite, la ClientScript propriété est utilisée pour injecter JavaScript qui affiche une boîte de message qui lit les produits ont été mis à jour.

Prenez une minute pour tester ce code. Visitez BatchUpdate.aspx un navigateur, modifiez un certain nombre de lignes, puis cliquez sur l’un des boutons Mettre à jour les produits. En supposant qu’il n’existe aucune erreur de validation d’entrée, vous devez voir une boîte de message qui lit les produits ont été mis à jour. Pour vérifier l’atomicité de la mise à jour, envisagez d’ajouter une contrainte aléatoire CHECK , comme celle qui interdit les UnitPrice valeurs de 1234.56. BatchUpdate.aspxEnsuite, modifiez un certain nombre d’enregistrements, en veillant à définir l’une des valeurs du UnitPrice produit sur la valeur interdite (1234.56). Cela doit entraîner une erreur lorsque vous cliquez sur Mettre à jour les produits avec les autres modifications pendant cette opération de traitement par lots restaurées sur leurs valeurs d’origine.

Une autreBatchUpdateméthode

La BatchUpdate méthode que nous venons d’examiner récupère tous les produits de la méthode BLL GetProducts , puis met à jour uniquement ces enregistrements qui apparaissent dans GridView. Cette approche est idéale si GridView n’utilise pas la pagination, mais si c’est le cas, il peut y avoir des centaines, des milliers ou des dizaines de milliers de produits, mais seulement dix lignes dans GridView. Dans ce cas, l’obtention de tous les produits de la base de données uniquement pour modifier 10 d’entre eux est inférieur à l’idéal.

Pour ces types de situations, envisagez plutôt d’utiliser la méthode suivante BatchUpdateAlternate :

Private Sub BatchUpdateAlternate()
    ' Enumerate the GridView's Rows collection and create a ProductRow
    Dim productsAPI As New ProductsBLL()
    Dim products As New Northwind.ProductsDataTable()
    For Each gvRow As GridViewRow In ProductsGrid.Rows
        ' Create a new ProductRow instance
        Dim productID As Integer = _
            Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
        Dim currentProductDataTable As Northwind.ProductsDataTable = _
            productsAPI.GetProductByProductID(productID)
        If currentProductDataTable.Rows.Count > 0 Then
            Dim product As Northwind.ProductsRow = currentProductDataTable(0)
            Dim productName As TextBox = _
                CType(gvRow.FindControl("ProductName"), TextBox)
            Dim categories As DropDownList = _
                CType(gvRow.FindControl("Categories"), DropDownList)
            Dim unitPrice As TextBox = _
                CType(gvRow.FindControl("UnitPrice"), TextBox)
            Dim discontinued As CheckBox = _
                CType(gvRow.FindControl("Discontinued"), CheckBox)
            ' Assign the user-entered values to the current ProductRow
            product.ProductName = productName.Text.Trim()
            If categories.SelectedIndex = 0 Then 
                product.SetCategoryIDNull() 
            Else 
                product.CategoryID = Convert.ToInt32(categories.SelectedValue)
            End If
            If unitPrice.Text.Trim().Length = 0 Then 
                product.SetUnitPriceNull() 
            Else 
                product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
            End If
            product.Discontinued = discontinued.Checked
            ' Import the ProductRow into the products DataTable
            products.ImportRow(product)
        End If
    Next
    ' Now have the BLL update the products data using a transaction
    productsAPI.UpdateProductsWithTransaction(products)
End Sub

BatchMethodAlternate commence par créer un nouveau nom vide ProductsDataTable nommé products. Il effectue ensuite les étapes de la collection GridView Rows et pour chaque ligne obtient les informations de produit particulières à l’aide de la méthode BLL.GetProductByProductID(productID) L’instance récupérée ProductsRow a ses propriétés mises à jour de la même façon que BatchUpdate, mais après la mise à jour de la ligne qu’elle est importée dans la products ProductsDataTable méthode DataTable.ImportRow(DataRow)

Une fois la For Each boucle terminée, products contient une ProductsRow instance pour chaque ligne dans GridView. Étant donné que chacune des ProductsRow instances a été ajoutée au products (au lieu de la mise à jour), si nous le transmettons de manière aveugle à la UpdateWithTransaction méthode, l’opération ProductsTableAdapter essaie d’insérer chacun des enregistrements dans la base de données. Au lieu de cela, nous devons spécifier que chacune de ces lignes a été modifiée (non ajoutée).

Pour ce faire, ajoutez une nouvelle méthode au BLL nommé UpdateProductsWithTransaction. UpdateProductsWithTransaction, illustré ci-dessous, définit l’ensemble RowState des instances de la Modified ProductsDataTable méthode DAL et passe ensuite la ProductsDataTable méthode DAL UpdateWithTransaction ProductsRow.

Public Function UpdateProductsWithTransaction _
    (ByVal products As Northwind.ProductsDataTable) As Integer
    ' Mark each product as Modified
    products.AcceptChanges()
    For Each product As Northwind.ProductsRow In products
        product.SetModified()
    Next
    ' Update the data via a transaction
    Return UpdateWithTransaction(products)
End Function

Résumé

GridView fournit des fonctionnalités intégrées d’édition par ligne, mais ne prend pas en charge la création d’interfaces entièrement modifiables. Comme nous l’avons vu dans ce tutoriel, ces interfaces sont possibles, mais nécessitent un peu de travail. Pour créer un GridView dans lequel chaque ligne est modifiable, nous devons convertir les champs GridView en TemplateFields et définir l’interface de modification dans les ItemTemplate s. En outre, mettre à jour tous les contrôles Web Bouton de type update doit être ajouté à la page, séparément de GridView. Ces gestionnaires d’événements Buttons Click doivent énumérer la collection GridView Rows , stocker les modifications dans un ProductsDataTableet transmettre les informations mises à jour dans la méthode BLL appropriée.

Dans le tutoriel suivant, nous allons voir comment créer une interface pour la suppression par lots. En particulier, chaque ligne GridView inclut une case à cocher et au lieu de mettre à jour tous les boutons -type, nous aurons des boutons Supprimer les lignes sélectionnées.

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 Teresa Murphy et David Suru. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.