Mise à jour par lots (VB)
par Scott Mitchell
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.
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 ItemTemplate
place 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.
Figure 2 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image ProductsBLL
de taille complète)
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.
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 ProductName
champs, CategoryName
UnitPrice
et 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
, CategoryName
et 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.
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
etDiscontinued
modification
La création des ProductName
interfaces , UnitPrice
et 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é ProductName
de 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.
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 .
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
Categories
sur . À 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 ItemTemplate
ObjectDataSource, 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.
Figure 8 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image CategoriesBLL
de taille complète)
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.
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.
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.
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.
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.
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.
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é False
sur . 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.
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, ProductsDataTable
elle 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.aspx
Ensuite, 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 autreBatchUpdate
mé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 ProductsDataTable
et 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.