Partager via


Utilisation de requêtes paramétrables avec SqlDataSource (C#)

par Scott Mitchell

Télécharger le PDF

Dans ce tutoriel, nous continuons notre regard sur le contrôle SqlDataSource et apprenons à définir des requêtes paramétrables. Les paramètres peuvent être spécifiés de manière déclarative et programmatique, et peuvent être extraits à partir d’un certain nombre d’emplacements tels que la chaîne de requête, l’état de session, d’autres contrôles, etc.

Présentation

Dans le tutoriel précédent, nous avons vu comment utiliser le contrôle SqlDataSource pour récupérer des données directement à partir d’une base de données. À l’aide de l’Assistant Configurer la source de données, nous pouvons sélectionner la base de données, puis choisir soit de sélectionner les colonnes à extraire depuis une table ou une vue, soit d'entrer une instruction SQL personnalisée, ou d'utiliser une procédure stockée. Si vous sélectionnez des colonnes à partir d’une table ou d’une vue ou entrez une instruction SQL personnalisée, la propriété du SelectCommand contrôle SqlDataSource reçoit l’instruction SQL SELECT ad hoc résultante et il s’agit de cette SELECT instruction exécutée lorsque la méthode SqlDataSource Select() est appelée (par programmation ou automatiquement à partir d’un contrôle Web de données).

Les instructions SQL SELECT utilisées dans les démonstrations précédentes du didacticiel n’ont pas de WHERE clauses. Dans une SELECT instruction, la WHERE clause peut être utilisée pour limiter les résultats retournés. Par exemple, pour afficher les noms des produits qui coûtent plus de 50,00 $, nous pourrions utiliser la requête suivante :

SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00

En règle générale, les valeurs utilisées dans une WHERE clause sont définies par une source externe, telle qu’une valeur de chaîne de requête, une variable de session ou une entrée utilisateur à partir d’un contrôle Web sur la page. Dans l’idéal, ces entrées sont spécifiées par le biais de l’utilisation de paramètres. Avec Microsoft SQL Server, les paramètres sont indiqués à l’aide @parameterNamede , comme dans :

SELECT ProductName
FROM Products
WHERE UnitPrice > @Price

SqlDataSource prend en charge les requêtes paramétrées, à la fois pour les instructions SELECT et INSERT, UPDATE, et les instructions DELETE. En outre, les valeurs de paramètre peuvent être extraites automatiquement à partir de diverses sources, l’état de session, les contrôles de la page, etc. ou peuvent être affectées par programmation. Dans ce tutoriel, nous allons voir comment définir des requêtes paramétrables, ainsi que comment spécifier les valeurs de paramètre de manière déclarative et programmatique.

Remarque

Dans le tutoriel précédent, nous avons comparé ObjectDataSource qui a été notre outil de choix sur les 46 premiers didacticiels avec SqlDataSource, notant leurs similitudes conceptuelles. Ces similitudes s’étendent également aux paramètres. Les paramètres de l'ObjectDataSource sont mappés aux paramètres d'entrée des méthodes de la couche logique métier. Avec SqlDataSource, les paramètres sont définis directement dans la requête SQL. Les deux contrôles ont des collections de paramètres pour leurs Select()méthodes, Insert()Update()et Delete() peuvent tous deux remplir ces valeurs de paramètres à partir de sources prédéfinies (valeurs de requête, variables de session, et ainsi de suite) ou attribuées par programme.

Création d’une requête paramétrable

L'Assistant de configuration de la source de données du contrôle SqlDataSource propose trois méthodes pour définir la commande à exécuter permettant de récupérer les enregistrements de la base de données.

  • En sélectionnant les colonnes d’une table ou d’une vue existante,
  • En entrant une instruction SQL personnalisée ou
  • En choisissant une procédure stockée

Lorsque vous choisissez des colonnes à partir d’une table ou d’une vue existante, les paramètres de la WHERE clause doivent être spécifiés via la boîte de dialogue Ajouter WHERE une clause. Toutefois, lors de la création d’une instruction SQL personnalisée, vous pouvez entrer les paramètres directement dans la WHERE clause (en utilisant @parameterName pour désigner chaque paramètre). Une procédure stockée se compose d’une ou plusieurs instructions SQL, et ces instructions peuvent être paramétrées. Toutefois, les paramètres utilisés dans les instructions SQL doivent être transmis en tant que paramètres d’entrée à la procédure stockée.

Étant donné que la création d'une requête paramétrée dépend de la manière dont le SqlDataSource s SelectCommand est spécifié, examinons les trois approches. Pour commencer, ouvrez la ParameterizedQueries.aspx page dans le dossier SqlDataSource, faites glisser un contrôle SqlDataSource à partir de la boîte à outils sur le Concepteur et définissez son ID sur Products25BucksAndUnderDataSource. Cliquez ensuite sur le lien Configurer la source de données à partir de la balise intelligente du contrôle. Sélectionnez la base de données à utiliser (NORTHWINDConnectionString) et cliquez sur Suivant.

Étape 1 : Ajout d’une clause WHERE lors de la sélection des colonnes à partir d’une table ou d’une vue

Lorsque vous sélectionnez les données à retourner à partir de la base de données avec le contrôle SqlDataSource, l’Assistant Configurer la source de données nous permet de choisir simplement les colonnes à retourner à partir d’une table ou d’une vue existante (voir la figure 1). Cela génère automatiquement une instruction SQL SELECT , qui est ce qui est envoyé à la base de données lorsque la méthode SqlDataSource Select() est appelée. Comme nous l'avons fait dans le tutoriel précédent, sélectionnez la table Products dans la liste déroulante, puis vérifiez les colonnes ProductID, ProductName et UnitPrice.

Sélectionner les colonnes à retourner à partir d’une table ou d’une vue

Figure 1 : Sélectionner les colonnes à retourner à partir d’une table ou d’une vue (cliquez pour afficher l’image de taille complète)

Pour inclure une WHERE clause dans l’instruction SELECT , cliquez sur le WHERE bouton, qui affiche la boîte de dialogue Ajouter WHERE une clause (voir la figure 2). Pour ajouter un paramètre pour limiter les résultats retournés par la SELECT requête, choisissez d’abord la colonne par laquelle filtrer les données. Ensuite, choisissez l’opérateur à utiliser pour le filtrage (=, <, <=, >etc.). Enfin, choisissez la source de la valeur du paramètre, par exemple à partir de la chaîne de requête ou de l’état de session. Après avoir configuré le paramètre, cliquez sur le bouton Ajouter pour l’inclure dans la SELECT requête.

Pour cet exemple, renvoyons uniquement les résultats où la UnitPrice valeur est inférieure ou égale à 25,00 $. Par conséquent, choisissez UnitPrice dans la liste déroulante Colonne et <= dans la liste déroulante Opérateur. Lorsque vous utilisez une valeur de paramètre codé en dur (par exemple, 25,00 $) ou si la valeur du paramètre doit être spécifiée par programme, sélectionnez Aucun dans la liste déroulante Source. Ensuite, entrez la valeur du paramètre codé en dur dans la zone de texte Valeur 25.00 et terminez le processus en cliquant sur le bouton Ajouter.

Limiter les résultats retournés à partir de la boîte de dialogue Ajouter une clause WHERE

Figure 2 : Limiter les résultats retournés à partir de la boîte de dialogue Ajouter WHERE une clause (cliquez pour afficher l’image de taille complète)

Après avoir ajouté le paramètre, cliquez sur OK pour retourner à l'assistant de configuration de la source de données. L’instruction SELECT située en bas de l’Assistant doit maintenant inclure une WHERE clause avec un paramètre nommé @UnitPrice:

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

Remarque

Si vous spécifiez plusieurs conditions dans la boîte de dialogue Ajouter WHERE Clause, l’Assistant les joint avec l’opérateur WHERE. Si vous devez inclure un OR dans la clause WHERE (par exemple WHERE UnitPrice <= @UnitPrice OR Discontinued = 1), vous devez générer l'instruction SELECT à l'aide de l'écran d'instructions SQL personnalisées.

Terminez la configuration de SqlDataSource (cliquez sur Suivant, puis Terminer), puis inspectez le balisage déclaratif de SqlDataSource. Le balisage inclut désormais une <SelectParameters> collection, qui indique les sources des paramètres dans le SelectCommand.

<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice]
        FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
    <SelectParameters>
        <asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
    </SelectParameters>
</asp:SqlDataSource>

Lorsque la méthode SqlDataSource est Select() appelée, la valeur du paramètre UnitPrice (25,00) est appliquée au paramètre @UnitPrice dans SelectCommand avant d’être envoyée à la base de données. Le résultat net est que seuls les produits inférieurs ou égaux à 25,00 $ sont retournés à partir du Products tableau. Pour confirmer cela, ajoutez un GridView à la page, liez-le à cette source de données, puis affichez la page via un navigateur. Vous ne devez voir que les produits répertoriés qui sont inférieurs ou égaux à 25,00 $, comme le confirme la figure 3.

Seuls les produits inférieurs ou égaux à 25,00 $ sont affichés

Figure 3 : Seuls ces produits inférieurs ou égaux à 25,00 $ sont affichés (Cliquez pour afficher l’image de taille complète)

Étape 2 : Ajout de paramètres à une instruction SQL personnalisée

Lorsque vous ajoutez une instruction SQL personnalisée, vous pouvez entrer la WHERE clause explicitement ou spécifier une valeur dans la cellule Filter du Générateur de requêtes. Pour illustrer cela, nous allons afficher uniquement ces produits dans un GridView dont les prix sont inférieurs à un certain seuil. Commencez par ajouter une zone de texte à la ParameterizedQueries.aspx page pour collecter cette valeur de seuil auprès de l’utilisateur. Définissez la propriété de TextBox à IDMaxPrice. Ajoutez un contrôle bouton Web et définissez la propriété de Text sur Afficher les produits correspondants.

Ensuite, faites glisser un GridView sur la page et, à partir de sa balise active, choisissez de créer un sqlDataSource nommé ProductsFilteredByPriceDataSource. Dans l’Assistant Configurer la source de données, passez à l’écran Spécifier une instruction SQL personnalisée ou une procédure stockée (voir la figure 4) et entrez la requête suivante :

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice

Après avoir entré la requête (manuellement ou via le Générateur de requêtes), cliquez sur Suivant.

Renvoyer uniquement ces produits inférieurs ou égaux à une valeur de paramètre

Figure 4 : Renvoyer uniquement ces produits inférieurs ou égaux à une valeur de paramètre (cliquez pour afficher l’image de taille complète)

Étant donné que la requête inclut des paramètres, l’écran suivant de l’Assistant nous invite à spécifier l'origine des valeurs de ces paramètres. Choisissez « Control » dans la liste déroulante Source du paramètre et MaxPrice (la valeur du contrôle « TextBox » ID) dans la liste déroulante ControlID. Vous pouvez également entrer une valeur par défaut facultative à utiliser dans le cas où l’utilisateur n’a entré aucun texte dans la MaxPrice zone de texte. Pendant ce temps, n’entrez pas de valeur par défaut.

La propriété Text de la TextBox MaxPrice est utilisée comme source de paramètre

Figure 5 : La MaxPrice propriété de Text TextBox est utilisée comme source de paramètre (cliquez pour afficher l’image de taille complète)

Terminez l’Assistant de configuration de la source de données en cliquant ensuite sur Suivant, puis sur Terminer. Le balisage déclaratif pour GridView, TextBox, Button et SqlDataSource suit :

Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
 
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
    Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            HtmlEncode="False" DataFormatString="{0:c}"
            SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT ProductName, UnitPrice 
        FROM Products WHERE UnitPrice <= @MaximumPrice">
    <SelectParameters>
        <asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
            PropertyName="Text" />
    </SelectParameters>
</asp:SqlDataSource>

Notez que le paramètre au sein de la section SqlDataSource <SelectParameters> est un ControlParameter, qui inclut des propriétés supplémentaires telles que ControlID et PropertyName. Lorsque la méthode SqlDataSource Select() est appelée, elle ControlParameter récupère la valeur de la propriété de contrôle Web spécifiée et l’affecte au paramètre correspondant dans le SelectCommand. Dans cet exemple, la propriété MaxPrice Text est utilisée comme valeur du paramètre @MaxPrice.

Prenez une minute pour afficher cette page via un navigateur. Lors de la première visite de la page ou chaque fois que textBox MaxPrice n’a pas de valeur, aucun enregistrement n’est affiché dans GridView.

Aucun enregistrement n’est affiché lorsque la zone de texte MaxPrice est vide

Figure 6 : Aucun enregistrement n’est affiché lorsque la MaxPrice zone de texte est vide (cliquez pour afficher l’image de taille complète)

La raison pour laquelle aucun produit n’est affiché est que, par défaut, une chaîne vide pour une valeur de paramètre est convertie en valeur de base de données NULL . Étant donné que la comparaison de [UnitPrice] <= NULL est toujours évaluée comme étant False, aucun résultat n'est retourné.

Entrez une valeur dans la zone de texte, par exemple 5.00, puis cliquez sur le bouton Afficher les produits correspondants. Lors du postback, le SqlDataSource informe le GridView que l’une de ses sources de paramètres a changé. Par conséquent, gridView se relie à SqlDataSource, affichant ces produits inférieurs ou égaux à 5,00 $.

Les produits inférieurs ou égaux à 5,00 $ sont affichés

Figure 7 : Les produits inférieurs ou égaux à 5,00 $ sont affichés (cliquez pour afficher l’image de taille complète)

Affichage initial de tous les produits

Au lieu d’afficher aucun produit lorsque la page est chargée pour la première fois, nous souhaitons peut-être afficher tous les produits. Une façon de répertorier tous les produits chaque fois que TextBox MaxPrice est vide consiste à définir la valeur par défaut du paramètre sur une valeur follement élevée, comme 10000000, car il est peu probable que Northwind Traders ait un inventaire dont le prix unitaire dépasse 1 000 000 $. Toutefois, cette approche est à courte vue et peut ne pas fonctionner dans d’autres situations.

Dans les didacticiels précédents - Paramètres déclaratifs et filtrage maître/détail avec une liste déroulante, nous avons été confrontés à un problème similaire. Notre solution consiste à mettre cette logique dans la couche logique métier. Plus précisément, la BLL a examiné la valeur entrante et, si elle était NULL ou une valeur réservée, l’appel a été acheminé vers la méthode DAL qui a retourné tous les enregistrements. Si la valeur entrante était une valeur de filtrage normale, un appel a été effectué à la méthode DAL qui a exécuté une instruction SQL qui a utilisé une clause paramétrable WHERE avec la valeur fournie.

Malheureusement, nous contournons l’architecture lors de l’utilisation de SqlDataSource. Au lieu de cela, nous devons personnaliser l’instruction SQL pour récupérer intelligemment tous les enregistrements si le @MaximumPrice paramètre est NULL ou une valeur réservée. Pour cet exercice, supposons que si le @MaximumPrice paramètre est égal à -1.0, tous les enregistrements doivent être retournés (-1.0 fonctionne comme une valeur réservée, car aucun produit ne peut avoir de valeur négative UnitPrice ). Pour ce faire, nous pouvons utiliser l’instruction SQL suivante :

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

Cette WHERE clause retourne tous les enregistrements si le @MaximumPrice paramètre est égal -1.0à . Si la valeur du paramètre n’est pas -1.0, seuls les produits dont UnitPrice la valeur est inférieure ou égale à la valeur du @MaximumPrice paramètre sont retournés. En définissant la valeur par défaut du paramètre @MaximumPrice au -1.0, lors du premier chargement de la page @MaximumPrice (ou chaque fois que la zone de texte @MaximumPrice est vide), -1.0 aura la valeur , et tous les produits seront affichés.

Maintenant, tous les produits sont affichés lorsque la zone de texte MaxPrice est vide

Figure 8 : Tous les produits sont affichés lorsque la MaxPrice zone de texte est vide (cliquez pour afficher l’image de taille complète)

Il y a quelques mises en garde à noter avec cette approche. Tout d’abord, sachez que le type de données du paramètre est déduit par son utilisation dans la requête SQL. Si vous modifiez la clause WHERE de @MaximumPrice = -1.0 à @MaximumPrice = -1, le temps d'exécution traite le paramètre en tant qu’entier. Si vous tentez ensuite d’affecter la MaxPrice zone de texte à une valeur décimale (par exemple, 5,00), une erreur se produit car elle ne peut pas convertir 5,00 en entier. Pour remédier à cela, veillez à utiliser @MaximumPrice = -1.0 dans la clause WHERE ou, mieux encore, définissez la propriété ControlParameter de l’objet Type à Decimal.

Deuxièmement, en ajoutant la clause OR @MaximumPrice = -1.0 de WHERE, le moteur de requête ne peut pas utiliser un index sur UnitPrice (en supposant qu’il en existe un), ce qui entraîne un balayage de table. Cela peut avoir un impact sur les performances s’il existe un nombre suffisamment élevé d’enregistrements dans la Products table. Une meilleure approche consisterait à déplacer cette logique vers une procédure stockée où une IF instruction effectuerait une SELECT requête à partir de la Products table sans WHERE clause lorsque tous les enregistrements doivent être retournés ou dont WHERE la clause contient uniquement les UnitPrice critères, afin qu’un index puisse être utilisé.

Étape 3 : Création et utilisation de procédures stockées paramétrables

Les procédures stockées peuvent inclure un ensemble de paramètres d’entrée qui peuvent ensuite être utilisés dans les instructions SQL définies dans la procédure stockée. Lors de la configuration de SqlDataSource pour utiliser une procédure stockée qui accepte les paramètres d’entrée, ces valeurs de paramètre peuvent être spécifiées à l’aide des mêmes techniques que les instructions SQL ad hoc.

Pour illustrer l’utilisation de procédures stockées dans SqlDataSource, nous allons créer une procédure stockée dans la base de données Northwind nommée GetProductsByCategory, qui accepte un paramètre nommé @CategoryID et retourne toutes les colonnes des produits dont CategoryID la colonne correspond @CategoryID. Pour créer une procédure stockée, accédez à l’Explorateur de serveurs et explorez la NORTHWND.MDF base de données. (Si vous ne voyez pas l’Explorateur de serveurs, affichez-le en accédant au menu Affichage et en sélectionnant l’option Explorateur de serveurs.)

Dans la NORTHWND.MDF base de données, cliquez avec le bouton droit sur le dossier Procédures stockées, choisissez Ajouter une nouvelle procédure stockée, puis entrez la syntaxe suivante :

CREATE PROCEDURE dbo.GetProductsByCategory
(
      @CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID

Cliquez sur l’icône Enregistrer (ou Ctrl+S) pour enregistrer la procédure stockée. Vous pouvez tester la procédure stockée en cliquant dessus avec le bouton droit dans le dossier Procédures stockées et en choisissant Exécuter. Cela vous invite à entrer les paramètres de la procédure stockée (@CategoryIDdans cette instance), après quoi les résultats seront affichés dans la fenêtre Sortie.

Procédure stockée GetProductsByCategory lorsqu’elle est exécutée avec une classe <span= @CategoryID de 1" />

Figure 9 : Procédure GetProductsByCategory stockée lorsqu’elle est exécutée avec une @CategoryID valeur de 1 (Cliquez pour afficher l’image de taille complète)

Utilisons cette procédure stockée pour afficher tous les produits de la catégorie Boissons dans un GridView. Ajoutez un nouveau GridView à la page et liez-le à un nouveau SqlDataSource nommé BeverageProductsDataSource. Passez à l’écran Spécifier une instruction SQL personnalisée ou une procédure stockée, sélectionnez le bouton radio de procédure stockée, puis choisissez la GetProductsByCategory procédure stockée dans la liste déroulante.

Sélectionnez la procédure stockée GetProductsByCategory dans la liste Drop-Down

Figure 10 : Sélectionner la GetProductsByCategory procédure stockée dans la liste des Drop-Down (cliquez pour afficher l’image de taille complète)

Étant donné que la procédure stockée accepte un paramètre d’entrée (@CategoryID), en cliquant sur Next, nous invite à spécifier la source de cette valeur de paramètre. Les boissons CategoryID sont 1. Laissez la liste déroulante Source du paramètre sur None et entrez 1 dans la zone de texte DefaultValue.

Utilisez une valeur Hard-Coded de 1 pour retourner les produits dans la catégorie Boissons

Figure 11 : Utiliser une valeur de Hard-Coded de 1 pour renvoyer les produits dans la catégorie Boissons (cliquez pour afficher l’image de taille complète)

Comme le montre le balisage déclaratif suivant, lors de l’utilisation d’une procédure stockée, la propriété SqlDataSource SelectCommand est définie sur le nom de la procédure stockée et la SelectCommandType propriété est définie StoredProceduresur , indiquant que le SelectCommand nom d’une procédure stockée plutôt qu’une instruction SQL ad hoc.

<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Testez la page dans un navigateur. Seuls les produits appartenant à la catégorie Boissons sont affichés, bien que tous les champs de produit soient affichés, car la GetProductsByCategory procédure stockée retourne toutes les colonnes de la Products table. Nous pourrions bien sûr limiter ou personnaliser les champs affichés dans GridView à partir de la boîte de dialogue Modifier les colonnes de GridView.

Toutes les boissons sont affichées

Figure 12 : Toutes les boissons sont affichées (cliquez pour afficher l’image pleine taille)

Étape 4 : Appel par programmation d’une instruction Select() de SqlDataSource

Les exemples que nous avons vus dans le didacticiel précédent et ce didacticiel ont jusqu’à présent lié des contrôles SqlDataSource directement à un GridView. Toutefois, les données du contrôle SqlDataSource sont accessibles par programmation et énumérées dans le code. Cela peut être particulièrement utile lorsque vous devez interroger des données pour l’inspecter, mais n’avez pas besoin de l’afficher. Au lieu d’écrire tout le code réutilisable ADO.NET pour vous connecter à la base de données, spécifier la commande et récupérer les résultats, vous pouvez laisser SqlDataSource gérer ce code monotone.

Pour illustrer l’utilisation des données de SqlDataSource par programmation, imaginez que votre patron vous a approché avec une demande de création d’une page web qui affiche le nom d’une catégorie sélectionnée aléatoirement et de ses produits associés. Autrement dit, lorsqu’un utilisateur visite cette page, nous voulons choisir de façon aléatoire une catégorie dans le Categories tableau, afficher le nom de la catégorie, puis répertorier les produits appartenant à cette catégorie.

Pour ce faire, nous avons besoin de deux contrôles SqlDataSource : un pour saisir une catégorie aléatoire dans la table Categories et l'autre pour obtenir les produits de cette catégorie. Nous allons créer le SqlDataSource qui récupère un enregistrement de catégorie aléatoire à cette étape ; l’étape 5 se concentre sur l’élaboration du SqlDataSource qui récupère les produits de la catégorie.

Commencez par ajouter un SqlDataSource à ParameterizedQueries.aspx et définissez-le ID sur RandomCategoryDataSource. Configurez-le pour qu’il utilise la requête SQL suivante :

SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()

ORDER BY NEWID() retourne les enregistrements triés dans l’ordre aléatoire (voir Utilisation NEWID() pour trier aléatoirement les enregistrements). SELECT TOP 1 retourne le premier enregistrement du jeu de résultats. Une fois assemblée, cette requête retourne les valeurs des colonnes CategoryID et CategoryName d’une catégorie unique sélectionnée de manière aléatoire.

Pour afficher la valeur de la CategoryName catégorie, ajoutez un contrôle Web Label à la page, définissez sa propriété sur ID, et effacez sa propriété CategoryNameLabel. Pour récupérer par programmation les données à partir d’un contrôle SqlDataSource, nous devons appeler sa Select() méthode. La Select() méthode attend un paramètre d’entrée unique de type DataSourceSelectArguments, qui spécifie la façon dont les données doivent être messageées avant d’être retournées. Cela peut inclure des instructions sur le tri et le filtrage des données, et est utilisé par les contrôles Web de données lors du tri ou de la pagination des données à partir d’un contrôle SqlDataSource. Pour notre exemple, cependant, nous n'avons pas besoin que les données soient modifiées avant qu'elles ne soient renvoyées, et par conséquent, nous allons transmettre l'objet DataSourceSelectArguments.Empty.

La Select() méthode retourne un objet qui implémente IEnumerable. Le type précis retourné dépend de la valeur de la propriété DataSourceMode du contrôle SqlDataSource. Comme indiqué dans le didacticiel précédent, cette propriété peut être définie sur une valeur de l’une ou l’autre DataSetDataReader. Si la valeur est définie DataSet, la Select() méthode renvoie un objet DataView ; si elle est définie DataReader, elle renvoie un objet qui implémente IDataReader. Étant donné que RandomCategoryDataSource SqlDataSource a sa DataSourceMode propriété définie DataSet sur (la valeur par défaut), nous allons utiliser un objet DataView.

Le code suivant montre comment récupérer les enregistrements à partir de RandomCategoryDataSource SqlDataSource en tant que DataView, ainsi que comment lire la CategoryName valeur de colonne à partir de la première ligne DataView :

protected void Page_Load(object sender, EventArgs e)
{
    // Get the data from the SqlDataSource as a DataView
    DataView randomCategoryView =
        (DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
    if (randomCategoryView.Count > 0)
    {
        // Assign the CategoryName value to the Label
        CategoryNameLabel.Text =
            string.Format("Here are Products in the {0} Category...",
                randomCategoryView[0]["CategoryName"].ToString());
    }
}

randomCategoryView[0] retourne le premier DataRowView dans DataView. randomCategoryView[0]["CategoryName"] retourne la valeur de la CategoryName colonne dans cette première ligne. Notez que DataView est faiblement typé. Pour référencer une valeur de colonne particulière, nous devons passer le nom de la colonne sous forme de chaîne (CategoryName, dans ce cas). La figure 13 montre le message affiché dans la CategoryNameLabel lors de la consultation de la page. Bien sûr, le nom de catégorie réel affiché est sélectionné de manière aléatoire par SqlDataSource RandomCategoryDataSource sur chaque visite de la page (y compris les postbacks).

Le nom de la catégorie sélectionnée aléatoirement est affiché

Figure 13 : Le nom de la catégorie sélectionnée aléatoirement s’affiche (cliquez pour afficher l’image de taille complète)

Remarque

Si la propriété DataSourceMode du contrôle SqlDataSource avait été définie à DataReader, la valeur de retour de la méthode Select() aurait dû être castée en IDataReader. Pour lire la valeur de la colonne à partir de la première ligne, nous utiliserions un code CategoryName comme suit :

if (randomCategoryReader.Read())
{
   string categoryName = randomCategoryReader["CategoryName"].ToString();
   ...
}

Avec la sélection aléatoire de SqlDataSource d’une catégorie, nous sommes prêts à ajouter GridView qui répertorie les produits de catégorie.

Remarque

Au lieu d’utiliser un contrôle Web Label pour afficher le nom de la catégorie, nous pourrions avoir ajouté un FormView ou DetailsView à la page, le liant à SqlDataSource. Toutefois, l’utilisation de l’étiquette nous a permis d’explorer comment appeler par programmation l’instruction SqlDataSource Select() et utiliser ses données résultantes dans le code.

Étape 5 : Affectation de valeurs de paramètre par programmation

Tous les exemples que nous avons vus jusqu’à présent dans ce tutoriel ont utilisé une valeur de paramètre codée en dur ou une des sources de paramètres prédéfinies (une valeur de chaîne de requête, un contrôle Web sur la page, etc.). Toutefois, les paramètres du contrôle SqlDataSource peuvent également être définis par programmation. Pour terminer notre exemple actuel, nous avons besoin d’un SqlDataSource qui retourne tous les produits appartenant à une catégorie spécifiée. Ce SqlDataSource aura un CategoryID paramètre dont la valeur doit être définie en fonction de la CategoryID valeur de colonne retournée par RandomCategoryDataSource SqlDataSource dans le Page_Load gestionnaire d’événements.

Commencez par ajouter un GridView à la page et liez-le à un nouveau SqlDataSource nommé ProductsByCategoryDataSource. Comme nous l’avons fait à l’étape 3, configurez SqlDataSource afin qu’il appelle la GetProductsByCategory procédure stockée. Laissez la liste déroulante Source du paramètre définie sur None, mais n’entrez pas de valeur par défaut, car nous allons définir cette valeur par défaut par programmation.

Capture d’écran montrant la fenêtre Configurer la source de données avec la source de paramètre définie sur None.

Figure 14 : Ne pas spécifier une source de paramètre ou une valeur par défaut (cliquez pour afficher l’image de taille complète)

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

<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Nous pouvons affecter le paramètre DefaultValue du CategoryID par programmation dans le gestionnaire d’événements Page_Load.

// Assign the ProductsByCategoryDataSource's
// CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
    randomCategoryView[0]["CategoryID"].ToString();

Avec cet ajout, la page inclut un GridView qui affiche les produits associés à la catégorie sélectionnée de manière aléatoire.

Capture d’écran montrant la page Catégorie sélectionnée aléatoirement.

Figure 15 : Ne pas spécifier une source de paramètre ou une valeur par défaut (cliquez pour afficher l’image de taille complète)

Résumé

SqlDataSource permet aux développeurs de pages de définir des requêtes paramétrables dont les valeurs de paramètre peuvent être codées en dur, extraites de sources de paramètres prédéfinies ou affectées par programme. Dans ce tutoriel, nous avons vu comment créer une requête paramétrable à partir de l’Assistant Configurer la source de données pour les requêtes SQL ad hoc et les procédures stockées. Nous avons également examiné l’utilisation de sources de paramètres codées en dur, d’un contrôle Web comme source de paramètre et de spécification par programmation de la valeur du paramètre.

Comme avec ObjectDataSource, SqlDataSource fournit également des fonctionnalités pour modifier ses données sous-jacentes. Dans le tutoriel suivant, nous allons examiner comment définir INSERT, UPDATEet DELETE des instructions avec SqlDataSource. Une fois ces instructions ajoutées, nous pouvons utiliser les fonctionnalités intégrées d’insertion, de modification et de suppression inhérentes aux contrôles GridView, DetailsView et FormView.

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. On peut le joindre à mitchell@4GuysFromRolla.com.

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 Scott Clyde, Randell Schmidt et Ken Pespisa. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.