Partager via


Création d’une couche d’accès aux données (VB)

par Scott Mitchell

Télécharger le PDF

Dans ce tutoriel, nous allons commencer à partir du début et créer la couche d’accès aux données (DAL), à l’aide de DataSets typés, pour accéder aux informations d’une base de données.

Introduction

En tant que développeurs web, nos vies tournent autour de l’utilisation des données. Nous créons des bases de données pour stocker les données, le code pour les récupérer et les modifier, ainsi que les pages web pour les collecter et les résumer. Il s’agit du premier didacticiel d’une longue série qui explorera les techniques d’implémentation de ces modèles courants dans ASP.NET 2.0. Nous allons commencer par créer une architecture logicielle composée d’une couche d’accès aux données (DAL) à l’aide de DataSets typés, d’une couche logique métier (BLL) qui applique des règles métier personnalisées et d’une couche de présentation composée de pages ASP.NET qui partagent une mise en page commune. Une fois que ce travail de base back-end a été posé, nous allons passer à la création de rapports, en montrant comment afficher, résumer, collecter et valider des données à partir d’une application web. Ces didacticiels sont destinés à être concis et fournissent des instructions pas à pas avec de nombreuses captures d’écran pour vous guider visuellement dans le processus. Chaque didacticiel est disponible dans les versions C# et Visual Basic et inclut un téléchargement du code complet utilisé. (Ce premier tutoriel est assez long, mais le reste est présenté dans des blocs beaucoup plus digestibles.)

Pour ces didacticiels, nous allons utiliser une version Microsoft SQL Server 2005 Express Edition de la base de données Northwind placée dans le App_Data répertoire. Outre le fichier de base de données, le App_Data dossier contient également les scripts SQL pour la création de la base de données, au cas où vous souhaitez utiliser une autre version de base de données. Si vous utilisez une autre version de SQL Server de la base de données Northwind, vous devez mettre à jour le NORTHWNDConnectionString paramètre dans le fichier de Web.config l’application. L’application web a été créée à l’aide de Visual Studio 2005 Professional Edition en tant que projet de site web basé sur le système de fichiers. Toutefois, tous les didacticiels fonctionneront également bien avec la version gratuite de Visual Studio 2005, Visual Web Developer.

Dans ce tutoriel, nous allons commencer à partir du début et créer la couche d’accès aux données (DAL), suivie de la création de la couche logique métier (BLL) dans le deuxième tutoriel, et de travailler sur la mise en page et la navigation dans le troisième. Les didacticiels après le troisième devront s’appuyer sur la base des trois premiers. Nous avons beaucoup à couvrir dans ce premier tutoriel, alors démarrez Visual Studio et commençons !

Étape 1 : Création d’un projet web et connexion à la base de données

Avant de pouvoir créer notre couche d’accès aux données (DAL), nous devons d’abord créer un site web et configurer notre base de données. Commencez par créer un site web basé sur le système de fichiers ASP.NET. Pour ce faire, accédez au menu Fichier et choisissez Nouveau site web, en affichant la boîte de dialogue Nouveau site web. Choisissez le modèle de site web ASP.NET, définissez la liste déroulante Emplacement sur Système de fichiers, choisissez un dossier pour placer le site web et définissez la langue sur Visual Basic.

Créer un site web basé sur le système de fichiers

Figure 1 : Créer un site web basé sur le système de fichiers (cliquez pour afficher l’image de taille complète)

Cela crée un site web avec une Default.aspx page ASP.NET, un App_Data dossier et un Web.config fichier.

Une fois le site web créé, l’étape suivante consiste à ajouter une référence à la base de données dans l’Explorateur de serveurs de Visual Studio. En ajoutant une base de données à l’Explorateur de serveurs, vous pouvez ajouter des tables, des procédures stockées, des vues, et ainsi de suite à partir de Visual Studio. Vous pouvez également afficher les données de table ou créer vos propres requêtes manuellement ou graphiquement via le Générateur de requêtes. En outre, lorsque nous créons les jeux de données typés pour le dal, nous devons pointer Visual Studio vers la base de données à partir de laquelle les jeux de données typés doivent être construits. Bien que nous puissions fournir ces informations de connexion à ce stade dans le temps, Visual Studio remplit automatiquement une liste déroulante des bases de données déjà inscrites dans l’Explorateur de serveurs.

Les étapes d’ajout de la base de données Northwind à l’Explorateur de serveurs dépendent de l’utilisation de la base de données SQL Server 2005 Express Edition dans le App_Data dossier ou si vous disposez d’une configuration de serveur de base de données Microsoft SQL Server 2000 ou 2005 que vous souhaitez utiliser à la place.

Utilisation d’une base de données dans leApp_Datadossier

Si vous n’avez pas de serveur de base de données SQL Server 2000 ou 2005 à vous connecter, ou si vous souhaitez simplement éviter d’avoir à ajouter la base de données à un serveur de base de données, vous pouvez utiliser la version SQL Server 2005 Express Edition de la base de données Northwind située dans le dossier du App_Data site web téléchargé (NORTHWND.MDF).

Une base de données placée dans le App_Data dossier est automatiquement ajoutée à l’Explorateur de serveurs. En supposant que SQL Server 2005 Express Edition soit installé sur votre ordinateur, vous devez voir un nœud nommé NORTHWND. MDF dans l’Explorateur de serveurs, que vous pouvez développer et explorer ses tables, vues, procédure stockée, etc. (voir la figure 2).

Le App_Data dossier peut également contenir des fichiers Microsoft Access .mdb , qui, comme leurs équivalents SQL Server, sont automatiquement ajoutés à l’Explorateur de serveurs. Si vous ne souhaitez pas utiliser d’options SQL Server, vous pouvez toujours installer la base de données et les applications Northwind Traders et les déplacer dans le App_Data répertoire. Gardez à l’esprit toutefois que les bases de données Access ne sont pas aussi riches en fonctionnalités que SQL Server et ne sont pas conçues pour être utilisées dans les scénarios de site web. En outre, quelques didacticiels de 35+ utilisent certaines fonctionnalités au niveau de la base de données qui ne sont pas prises en charge par Access.

Connexion à la base de données dans un serveur de base de données Microsoft SQL Server 2000 ou 2005

Vous pouvez également vous connecter à une base de données Northwind installée sur un serveur de base de données. Si le serveur de base de données n’a pas encore installé la base de données Northwind, vous devez d’abord l’ajouter au serveur de base de données en exécutant le script d’installation inclus dans le téléchargement de ce didacticiel.

Une fois la base de données installée, accédez à l’Explorateur de serveurs dans Visual Studio, cliquez avec le bouton droit sur le nœud Connexions de données, puis choisissez Ajouter une connexion. Si vous ne voyez pas l’Explorateur de serveurs accéder à l’Affichage/Explorateur de serveurs, ou appuyez sur Ctrl+Alt+S. La boîte de dialogue Ajouter une connexion s’affiche, où vous pouvez spécifier le serveur auquel se connecter, les informations d’authentification et le nom de la base de données. Une fois que vous avez correctement configuré les informations de connexion de base de données et cliqué sur le bouton OK, la base de données est ajoutée en tant que nœud sous le nœud Connexions de données. Vous pouvez développer le nœud de base de données pour explorer ses tables, vues, procédures stockées, et ainsi de suite.

Ajouter une connexion à la base de données Northwind de votre serveur de base de données

Figure 2 : Ajouter une connexion à la base de données Northwind de votre serveur de base de données Northwind

Étape 2 : Création de la couche d’accès aux données

Lorsque vous utilisez des données, une option consiste à incorporer la logique spécifique aux données directement dans la couche de présentation (dans une application web, les pages ASP.NET composent la couche de présentation). Cela peut prendre la forme d’écrire ADO.NET code dans la partie de code de la page ASP.NET ou à l’aide du contrôle SqlDataSource à partir de la partie de balisage. Dans les deux cas, cette approche couple étroitement la logique d’accès aux données avec la couche de présentation. Toutefois, l’approche recommandée consiste à séparer la logique d’accès aux données de la couche présentation. Cette couche distincte est appelée couche d’accès aux données, DAL pour un court terme, et est généralement implémentée en tant que projet de bibliothèque de classes distinct. Les avantages de cette architecture en couches sont bien documentés (consultez la section « Autres lectures » à la fin de ce tutoriel pour plus d’informations sur ces avantages) et est l’approche que nous adopterons dans cette série.

Tout le code spécifique à la source de données sous-jacente, comme la création d’une connexion à la base de données, l’émissionSELECT, INSERTUPDATEles commandes et DELETE ainsi de suite doit se trouver dans le DAL. La couche de présentation ne doit pas contenir de références à ce code d’accès aux données, mais doit plutôt effectuer des appels au dal pour toutes les demandes de données. Les couches d’accès aux données contiennent généralement des méthodes d’accès aux données de base de données sous-jacentes. La base de données Northwind, par exemple, comporte Products et Categories des tables qui enregistrent les produits à vendre et les catégories auxquelles elles appartiennent. Dans notre DAL, nous aurons des méthodes comme :

  • GetCategories(), qui retourne des informations sur toutes les catégories
  • GetProducts(), qui retourne des informations sur tous les produits
  • GetProductsByCategoryID(categoryID), qui retourne tous les produits appartenant à une catégorie spécifiée
  • GetProductByProductID(productID), qui retourne des informations sur un produit particulier

Ces méthodes, lorsqu’elles sont appelées, se connectent à la base de données, émettent la requête appropriée et retournent les résultats. Comment nous renvoyons ces résultats est important. Ces méthodes peuvent simplement retourner un DataSet ou DataReader rempli par la requête de base de données, mais dans l’idéal, ces résultats doivent être retournés à l’aide d’objets fortement typés. Un objet fortement typé est un objet dont le schéma est défini de manière rigide au moment de la compilation, tandis que l’inverse, un objet faiblement typé, est celui dont le schéma n’est pas connu tant que l’exécution n’est pas terminée.

Par exemple, DataReader et DataSet (par défaut) sont des objets faiblement typés, car leur schéma est défini par les colonnes retournées par la requête de base de données utilisée pour les remplir. Pour accéder à une colonne particulière à partir d’un DataTable faiblement typé, nous devons utiliser la syntaxe suivante : DataTable.Rows(index)("columnName"). La saisie libre de DataTable dans cet exemple est exposée par le fait que nous devons accéder au nom de colonne à l’aide d’une chaîne ou d’un index ordinal. Un DataTable fortement typé, d’autre part, aura chacune de ses colonnes implémentées en tant que propriétés, ce qui entraîne le code qui ressemble à : DataTable.Rows(index).columnName.

Pour retourner des objets fortement typés, les développeurs peuvent créer leurs propres objets métier personnalisés ou utiliser des DataSets typés. Un objet métier est implémenté par le développeur en tant que classe dont les propriétés reflètent généralement les colonnes de la table de base de données sous-jacente que représente l’objet métier. Un DataSet typé est une classe générée pour vous par Visual Studio en fonction d’un schéma de base de données et dont les membres sont fortement typés en fonction de ce schéma. Le DataSet typé se compose de classes qui étendent les classes dataSet, DataTable et DataRow ADO.NET. Outre les DataTables fortement typés, les DataSets typés incluent désormais TableAdapters, qui sont des classes avec des méthodes permettant de remplir les DataTables de DataSet et de propager les modifications dans les DataTables dans la base de données.

Remarque

Pour plus d’informations sur les avantages et les inconvénients de l’utilisation de DataSets typés par rapport aux objets métier personnalisés, reportez-vous à la conception de composants de couche Données et à la transmission de données via des niveaux.

Nous allons utiliser des DataSets fortement typés pour l’architecture de ces didacticiels. La figure 3 illustre le flux de travail entre les différentes couches d’une application qui utilise des jeux de données typés.

Tout le code d’accès aux données est relégué au dal

Figure 3 : Tout le code d’accès aux données est relégué au dal (cliquez pour afficher l’image de taille complète)

Création d’un jeu de données typé et d’un adaptateur de table

Pour commencer à créer notre DAL, nous commençons par ajouter un DataSet Typd à notre projet. Pour ce faire, cliquez avec le bouton droit sur le nœud du projet dans le Explorateur de solutions et choisissez Ajouter un nouvel élément. Sélectionnez l’option DataSet dans la liste des modèles et nommez-la Northwind.xsd.

Choisir d’ajouter un nouveau jeu de données à votre projet

Figure 4 : Choisir d’ajouter un nouveau jeu de données à votre projet (cliquez pour afficher l’image de taille complète)

Après avoir cliqué sur Ajouter, lorsque vous êtes invité à ajouter le DataSet au App_Code dossier, choisissez Oui. Le Concepteur du Jeu de données typé s’affiche, et l’Assistant Configuration de TableAdapter démarre, ce qui vous permet d’ajouter votre premier TableAdapter au Jeu de données Typé.

Un DataSet typé sert de collection fortement typée de données ; il se compose d’instances DataTable fortement typées, chacune d’elles étant à son tour composée d’instances DataRow fortement typées. Nous allons créer un DataTable fortement typé pour chacune des tables de base de données sous-jacentes avec lesquelles nous devons travailler dans cette série de didacticiels. Commençons par créer un DataTable pour la Products table.

N’oubliez pas que les DataTables fortement typés n’incluent aucune information sur l’accès aux données à partir de leur table de base de données sous-jacente. Pour récupérer les données pour remplir dataTable, nous utilisons une classe TableAdapter, qui fonctionne comme couche d’accès aux données. Pour notre Products DataTable, TableAdapter contiendra les méthodes GetProducts(), GetProductByCategoryID(categoryID)et ainsi de suite, nous allons appeler à partir de la couche de présentation. Le rôle de DataTable est de servir d’objets fortement typés utilisés pour transmettre des données entre les couches.

L’Assistant Configuration de TableAdapter commence par vous inviter à sélectionner la base de données à utiliser. La liste déroulante affiche ces bases de données dans l’Explorateur de serveurs. Si vous n’avez pas ajouté la base de données Northwind à l’Explorateur de serveurs, vous pouvez cliquer sur le bouton Nouvelle connexion pour ce faire.

Choisissez la base de données Northwind dans la liste déroulante

Figure 5 : Choisir la base de données Northwind dans la liste déroulante (cliquez pour afficher l’image de taille complète)

Après avoir sélectionné la base de données et cliqué sur Suivant, vous êtes invité à enregistrer le chaîne de connexion dans le Web.config fichier. En enregistrant le chaîne de connexion vous éviterez de le coder en dur dans les classes TableAdapter, ce qui simplifie les choses si les informations chaîne de connexion changent à l’avenir. Si vous choisissez d’enregistrer le chaîne de connexion dans le fichier de configuration, il est placé dans la <connectionStrings> section, qui peut éventuellement être chiffré pour une sécurité améliorée ou modifié ultérieurement via la nouvelle page de propriétés ASP.NET 2.0 dans l’outil d’administration de l’interface utilisateur utilisateur IIS, qui est plus idéal pour les administrateurs.

Enregistrer la chaîne de connexion sur Web.config

Figure 6 : Enregistrer la chaîne Web.config de connexion dans (cliquez pour afficher l’image de taille complète)

Ensuite, nous devons définir le schéma pour le premier DataTable fortement typé et fournir la première méthode pour notre TableAdapter à utiliser lors du remplissage du DataSet fortement typé. Ces deux étapes sont effectuées simultanément en créant une requête qui retourne les colonnes de la table que nous voulons refléter dans notre DataTable. À la fin de l’Assistant, nous allons donner un nom de méthode à cette requête. Une fois cette opération effectuée, cette méthode peut être appelée à partir de notre couche de présentation. La méthode exécute la requête définie et remplit un DataTable fortement typé.

Pour commencer à définir la requête SQL, nous devons d’abord indiquer comment le TableAdapter doit émettre la requête. Nous pouvons utiliser une instruction SQL ad hoc, créer une procédure stockée ou utiliser une procédure stockée existante. Pour ces didacticiels, nous allons utiliser des instructions SQL ad hoc.

Interroger les données à l’aide d’une instruction SQL ad hoc

Figure 7 : Interroger les données à l’aide d’une instruction SQL ad hoc (Cliquez pour afficher l’image de taille complète)

À ce stade, nous pouvons taper manuellement la requête SQL. Lors de la création de la première méthode dans TableAdapter, vous souhaitez généralement que la requête retourne les colonnes qui doivent être exprimées dans le DataTable correspondant. Pour ce faire, nous pouvons créer une requête qui retourne toutes les colonnes et toutes les lignes de la Products table :

Entrer la requête SQL dans la zone de texte

Figure 8 : Entrer la requête SQL dans la zone de texte (Cliquez pour afficher l’image de taille complète)

Vous pouvez également utiliser le Générateur de requêtes et construire graphiquement la requête, comme illustré dans la figure 9.

Créez la requête graphiquement, via l’Éditeur de requête

Figure 9 : Créer la requête graphiquement, via le Éditeur de requête (cliquez pour afficher l’image de taille complète)

Après avoir créé la requête, mais avant de passer à l’écran suivant, cliquez sur le bouton Options avancées. Dans les projets de site web, « Générer des instructions Insert, Update et Delete » est la seule option avancée sélectionnée par défaut ; si vous exécutez cet Assistant à partir d’une bibliothèque de classes ou d’un projet Windows, l’option « Utiliser la concurrence optimiste » est également sélectionnée. Laissez l’option « Utiliser la concurrence optimiste » désactivée pour l’instant. Nous examinerons l’accès concurrentiel optimiste dans les prochains didacticiels.

Sélectionnez uniquement l’option Générer l’insertion, la mise à jour et la suppression des instructions

Figure 10 : Sélectionner uniquement l’option Générer l’insertion, la mise à jour et la suppression des instructions (Cliquez pour afficher l’image de taille complète)

Après avoir vérifié les options avancées, cliquez sur Suivant pour passer à l’écran final. Ici, nous sommes invités à sélectionner les méthodes à ajouter à TableAdapter. Il existe deux modèles pour remplir des données :

  • Remplissez un DataTable avec cette approche, une méthode est créée qui prend un DataTable en tant que paramètre et la remplit en fonction des résultats de la requête. La classe ADO.NET DataAdapter, par exemple, implémente ce modèle avec sa Fill() méthode.
  • Retournez un DataTable avec cette approche, la méthode crée et remplit dataTable pour vous et la retourne à mesure que les méthodes retournent la valeur.

Vous pouvez utiliser TableAdapter pour implémenter un ou les deux modèles suivants. Vous pouvez également renommer les méthodes fournies ici. Laissez les deux cases à cocher activées, même si nous utiliserons uniquement le dernier modèle dans ces didacticiels. En outre, renommons la méthode plutôt générique GetData en GetProducts.

Si cette case est cochée, la case finale « GenerateDBDirectMethods », crée Insert(), Update()et Delete() les méthodes pour TableAdapter. Si vous laissez cette option désactivée, toutes les mises à jour doivent être effectuées via la méthode unique Update() de TableAdapter, qui prend dans l’ensemble de données typé, un DataTable, un DataRow unique ou un tableau de DataRows. (Si vous avez décoché l’option « Générer des instructions d’insertion, de mise à jour et de suppression » des propriétés avancées de la figure 9, cette case à cocher n’aura aucun effet.) Laissez cette case à cocher activée.

Modifier le nom de la méthode de GetData en GetProducts

Figure 11 : Modifier le nom de la méthode à GetProducts partir de GetData (Cliquez pour afficher l’image de taille complète)

Terminez l’Assistant en cliquant sur Terminer. Une fois l’Assistant fermé, nous sommes retournés au Concepteur DataSet qui affiche le DataTable que nous venons de créer. Vous pouvez voir la liste des colonnes dans DataTable Products (ProductID, ProductNameetc.), ainsi que les méthodes du ProductsTableAdapter (Fill() et GetProducts()).

DataTable et ProductsTableAdapter ont été ajoutés à l’ensemble de données typé

Figure 12 : DataTable Products et ProductsTableAdapter ont été ajoutés à l’ensemble de données typé (cliquez pour afficher l’image de taille complète)

À ce stade, nous disposons d’un Jeu de données typé avec une seule DataTable (Northwind.Products) et une classe DataAdapter fortement typée (NorthwindTableAdapters.ProductsTableAdapter) avec une GetProducts() méthode. Ces objets peuvent être utilisés pour accéder à une liste de tous les produits à partir de code comme :

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products as Northwind.ProductsDataTable
products = productsAdapter.GetProducts()
For Each productRow As Northwind.ProductsRow In products
    Response.Write("Product: " & productRow.ProductName & "<br />")
Next

Ce code n’a pas exigé que nous écrivions un bit de code spécifique à l’accès aux données. Nous n’avons pas dû instancier des classes ADO.NET, nous n’avons pas dû faire référence à des chaîne de connexion, requêtes SQL ou procédures stockées. Au lieu de cela, TableAdapter fournit le code d’accès aux données de bas niveau pour nous.

Chaque objet utilisé dans cet exemple est également fortement typé, ce qui permet à Visual Studio de fournir intelliSense et la vérification du type au moment de la compilation. Et le meilleur de tous les DataTables retournés par TableAdapter peut être lié à ASP.NET contrôles Web de données, tels que GridView, DetailsView, DropDownList, CheckBoxList, etc. L’exemple suivant illustre la liaison de DataTable retournée par la GetProducts() méthode à un GridView dans seulement trois lignes de code au sein du Page_Load gestionnaire d’événements.

AllProducts.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="AllProducts.aspx.vb"
    Inherits="AllProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>View All Products in a GridView</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            All Products</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

AllProducts.aspx.vb

Imports NorthwindTableAdapters
Partial Class AllProducts
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim productsAdapter As New ProductsTableAdapter
        GridView1.DataSource = productsAdapter.GetProducts()
        GridView1.DataBind()
    End Sub
End Class

La liste des produits s’affiche dans un GridView

Figure 13 : La liste des produits s’affiche dans un GridView (cliquez pour afficher une image de taille complète)

Bien que cet exemple exigeait que nous écrivions trois lignes de code dans le gestionnaire d’événements de Page_Load notre page ASP.NET, dans les didacticiels futurs, nous allons examiner comment utiliser ObjectDataSource pour récupérer de manière déclarative les données à partir du dal. Avec ObjectDataSource, nous n’aurons pas besoin d’écrire de code et obtiendrons également la prise en charge de la pagination et du tri !

Étape 3 : Ajout de méthodes paramétrables à la couche d’accès aux données

À ce stade, notre ProductsTableAdapter classe a une méthode, GetProducts()qui retourne tous les produits dans la base de données. Tout en étant en mesure de travailler avec tous les produits est certainement utile, il existe des moments où nous voulons récupérer des informations sur un produit spécifique, ou tous les produits appartenant à une catégorie particulière. Pour ajouter de telles fonctionnalités à notre couche d’accès aux données, nous pouvons ajouter des méthodes paramétrables à TableAdapter.

Ajoutons la GetProductsByCategoryID(categoryID) méthode. Pour ajouter une nouvelle méthode au dal, revenez au Concepteur DataSet, cliquez avec le bouton droit dans la ProductsTableAdapter section, puis choisissez Ajouter une requête.

Cliquez avec le bouton droit sur TableAdapter et choisissez Ajouter une requête

Figure 14 : Cliquez avec le bouton droit sur TableAdapter et choisissez Ajouter une requête

Nous sommes d’abord invités à savoir si nous voulons accéder à la base de données à l’aide d’une instruction SQL ad hoc ou d’une procédure stockée nouvelle ou existante. Nous allons choisir d’utiliser à nouveau une instruction SQL ad hoc. Ensuite, nous sommes invités à savoir quel type de requête SQL nous aimerions utiliser. Étant donné que nous voulons retourner tous les produits appartenant à une catégorie spécifiée, nous voulons écrire une SELECT instruction qui retourne des lignes.

Choisir de créer une instruction SELECT qui renvoie des lignes

Figure 15 : Choisir de créer une SELECT instruction qui renvoie des lignes (cliquez pour afficher l’image de taille complète)

L’étape suivante consiste à définir la requête SQL utilisée pour accéder aux données. Étant donné que nous voulons retourner uniquement les produits qui appartiennent à une catégorie particulière, j’utilise la même SELECT instruction de GetProducts(), mais ajoutez la clause suivante WHERE : WHERE CategoryID = @CategoryID Le @CategoryID paramètre indique à l’Assistant TableAdapter que la méthode que nous créons nécessite un paramètre d’entrée du type correspondant (à savoir, un entier nullable).

Entrer une requête pour renvoyer uniquement des produits dans une catégorie spécifiée

Figure 16 : Entrer une requête pour renvoyer uniquement des produits dans une catégorie spécifiée (cliquez pour afficher l’image de taille complète)

Au cours de la dernière étape, nous pouvons choisir les modèles d’accès aux données à utiliser, ainsi que personnaliser les noms des méthodes générées. Pour le modèle De remplissage, nous allons remplacer le nom FillByCategoryID et le retour d’un modèle de retour DataTable (les GetX méthodes), utilisons GetProductsByCategoryID.

Choisir les noms des méthodes TableAdapter

Figure 17 : Choisir les noms des méthodes TableAdapter (Cliquez pour afficher l’image de taille complète)

Une fois l’Assistant terminé, le Concepteur DataSet inclut les nouvelles méthodes TableAdapter.

Les produits peuvent maintenant être interrogés par catégorie

Figure 18 : Les produits peuvent maintenant être interrogés par catégorie

Prenez un moment pour ajouter une GetProductByProductID(productID) méthode à l’aide de la même technique.

Ces requêtes paramétrables peuvent être testées directement à partir du Concepteur DataSet. Cliquez avec le bouton droit sur la méthode dans TableAdapter et choisissez Aperçu des données. Ensuite, entrez les valeurs à utiliser pour les paramètres, puis cliquez sur Aperçu.

Ces produits appartenant à la catégorie Boissons sont affichés

Figure 19 : Ces produits appartenant à la catégorie Boissons sont affichés (cliquez pour afficher l’image de taille complète)

Avec la GetProductsByCategoryID(categoryID) méthode de notre dal, nous pouvons maintenant créer une page ASP.NET qui affiche uniquement ces produits dans une catégorie spécifiée. L’exemple suivant montre tous les produits qui se trouvent dans la catégorie Boissons, qui ont une CategoryID valeur de 1.

Beverages.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Beverages.aspx.vb"
    Inherits="Beverages" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Beverages</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

Beverages.aspx.vb

Imports NorthwindTableAdapters
Partial Class Beverages
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim productsAdapter As New ProductsTableAdapter
        GridView1.DataSource =
         productsAdapter.GetProductsByCategoryID(1)
        GridView1.DataBind()
    End Sub
End Class

Ces produits dans la catégorie Boissons sont affichés

Figure 20 : Ces produits de la catégorie Boissons sont affichés (cliquez pour afficher l’image de taille complète)

Étape 4 : Insertion, mise à jour et suppression de données

Il existe deux modèles couramment utilisés pour l’insertion, la mise à jour et la suppression de données. Le premier modèle, que j’appellerai le modèle direct de base de données, implique la création de méthodes qui, lorsqu’elles sont appelées, émettent un INSERT, UPDATEou DELETE une commande à la base de données qui fonctionne sur un enregistrement de base de données unique. Ces méthodes sont généralement passées dans une série de valeurs scalaires (entiers, chaînes, booléens, DateTimes, etc.) qui correspondent aux valeurs à insérer, mettre à jour ou supprimer. Par exemple, avec ce modèle pour la table, la Products méthode delete prend un paramètre entier, indiquant l’enregistrement ProductID à supprimer, tandis que la méthode insert prend une chaîne pour le ProductName, une décimale pour le UnitPrice, un entier pour le , un entier pour le UnitsOnStock, et ainsi de suite.

Chaque demande d’insertion, de mise à jour et de suppression est envoyée immédiatement à la base de données

Figure 21 : Chaque demande d’insertion, de mise à jour et de suppression est envoyée immédiatement à la base de données (cliquez pour afficher l’image de taille complète)

L’autre modèle, auquel je vais faire référence en tant que modèle de mise à jour par lot, consiste à mettre à jour un jeu de données entier, DataTable ou une collection de DataRows dans un appel de méthode. Avec ce modèle, un développeur supprime, insère et modifie DataRows dans un DataTable, puis passe ces DataRows ou DataTable dans une méthode de mise à jour. Cette méthode énumère ensuite les DataRows passées, détermine si elles ont été modifiées, ajoutées ou supprimées (via la valeur de propriété RowState de DataRow) et émet la demande de base de données appropriée pour chaque enregistrement.

Toutes les modifications sont synchronisées avec la base de données lorsque la méthode de mise à jour est appelée

Figure 22 : Toutes les modifications sont synchronisées avec la base de données lorsque la méthode de mise à jour est appelée (cliquez pour afficher l’image de taille complète)

TableAdapter utilise le modèle de mise à jour par lot par défaut, mais prend également en charge le modèle direct de base de données. Étant donné que nous avons sélectionné l’option « Générer des instructions Insert, Update et Delete » dans les propriétés avancées lors de la création de notre TableAdapter, la ProductsTableAdapter méthode contient une Update() méthode, qui implémente le modèle de mise à jour par lots. Plus précisément, TableAdapter contient une Update() méthode qui peut être transmise à l’ensemble de données typé, à un DataTable fortement typé ou à un ou plusieurs DataRows. Si vous avez laissé la case à cocher « GenerateDBDirectMethods » cochée lors de la première création de TableAdapter, le modèle direct de base de données sera également implémenté via Insert(), Update()et Delete() les méthodes.

Les deux modèles de modification de données utilisent les propriétés et DeleteCommand UpdateCommandles propriétés de InsertCommandTableAdapter pour émettre leurs commandes UPDATEet DELETE leurs INSERTcommandes dans la base de données. Vous pouvez inspecter et modifier les InsertCommandpropriétés et UpdateCommandDeleteCommand les propriétés en cliquant sur TableAdapter dans le Concepteur DataSet, puis en accédant au Fenêtre Propriétés. (Vérifiez que vous avez sélectionné TableAdapter et que l’objet ProductsTableAdapter est celui sélectionné dans la liste déroulante de la Fenêtre Propriétés.)

TableAdapter possède des propriétés InsertCommand, UpdateCommand et DeleteCommand

Figure 23 : TableAdapter a InsertCommand, UpdateCommandet DeleteCommand propriétés (Cliquez pour afficher l’image de taille complète)

Pour examiner ou modifier l’une de ces propriétés de commande de base de données, cliquez sur la CommandText sous-propriété, ce qui affiche le Générateur de requêtes.

Configurer les instructions INSERT, UPDATE et DELETE dans le Générateur de requêtes

Figure 24 : Configurer les instructions et DELETE les INSERTUPDATEinstructions dans le Générateur de requêtes (cliquez pour afficher l’image de taille complète)

L’exemple de code suivant montre comment utiliser le modèle de mise à jour par lots pour doubler le prix de tous les produits qui ne sont pas abandonnés et qui ont 25 unités en stock ou moins :

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products As Northwind.ProductsDataTable = productsAdapter.GetProducts()
For Each product As Northwind.ProductsRow In products
   If Not product.Discontinued AndAlso product.UnitsInStock <= 25 Then
      product.UnitPrice *= 2
   End if
Next
productsAdapter.Update(products)

Le code ci-dessous montre comment utiliser le modèle direct de base de données pour supprimer par programme un produit particulier, puis en mettre à jour un, puis en ajouter un nouveau :

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
productsAdapter.Delete(3)
productsAdapter.Update( _
    "Chai", 1, 1, "10 boxes x 20 bags", 18.0, 39, 15, 10, false, 1)
productsAdapter.Insert( _
    "New Product", 1, 1, "12 tins per carton", 14.95, 15, 0, 10, false)

Création de méthodes Insert, Update et Delete personnalisées

Les Insert()méthodes créées Delete() Update()par la méthode directe de base de données peuvent être un peu fastidieuses, en particulier pour les tables avec de nombreuses colonnes. En examinant l’exemple de code précédent, sans l’aide d’IntelliSense, il n’est pas particulièrement clair ce que Products la colonne de table mappe à chaque paramètre d’entrée aux méthodes et Insert() aux Update() méthodes. Il peut arriver que nous souhaitions mettre à jour une seule colonne ou deux, ou si vous souhaitez une méthode personnalisée Insert() qui retournera peut-être la valeur du champ (incrément automatique) de l’enregistrement IDENTITY nouvellement inséré.

Pour créer une telle méthode personnalisée, revenez au Concepteur DataSet. Cliquez avec le bouton droit sur TableAdapter et choisissez Ajouter une requête, en retournant à l’Assistant TableAdapter. Sur le deuxième écran, nous pouvons indiquer le type de requête à créer. Créons une méthode qui ajoute un nouveau produit, puis retourne la valeur de l’enregistrement ProductIDnouvellement ajouté. Par conséquent, choisissez de créer une INSERT requête.

Créer une méthode pour ajouter une nouvelle ligne à la table Products

Figure 25 : Créer une méthode pour ajouter une nouvelle ligne à la Products table (cliquez pour afficher l’image de taille complète)

Sur l’écran suivant, les InsertCommandécrans s’affichent CommandText . Augmentez cette requête en ajoutant SELECT SCOPE_IDENTITY() à la fin de la requête, ce qui retourne la dernière valeur d’identité insérée dans une IDENTITY colonne dans la même étendue. (Consultez la documentation technique pour plus d’informations sur SCOPE_IDENTITY() les raisons pour lesquelles vous souhaitez probablement utiliser SCOPE_IDENTITY() au lieu de @@IDENTITY.) Veillez à mettre fin à l’instruction INSERT avec un point-virgule avant d’ajouter l’instruction SELECT .

Augmenter la requête pour retourner la valeur SCOPE_IDENTITY()

Figure 26 : Augmenter la requête pour retourner la valeur (cliquez pour afficher l’image SCOPE_IDENTITY()de taille complète)

Enfin, nommez la nouvelle méthode InsertProduct.

Définir le nom de la nouvelle méthode sur InsertProduct

Figure 27 : Définir le nom de la nouvelle méthode InsertProduct sur (Cliquez pour afficher l’image de taille complète)

Lorsque vous revenez au Concepteur DataSet, vous verrez que le ProductsTableAdapter fichier contient une nouvelle méthode. InsertProduct Si cette nouvelle méthode n’a pas de paramètre pour chaque colonne de la Products table, vous avez oublié de mettre fin à l’instruction INSERT avec un point-virgule. Configurez la InsertProduct méthode et vérifiez que vous disposez d’un point-virgule limitant les instructions et SELECT les INSERT instructions.

Par défaut, les méthodes insert émettent des méthodes non-requête, ce qui signifie qu’elles retournent le nombre de lignes affectées. Toutefois, nous voulons que la InsertProduct méthode retourne la valeur retournée par la requête, et non le nombre de lignes affectées. Pour ce faire, ajustez la propriété de ExecuteMode la InsertProduct méthode à Scalar.

Remplacez la propriété ExecuteMode par Scalar

Figure 28 : Modifier la propriété Scalar en (Cliquez pour afficher l’image ExecuteModede taille complète)

Le code suivant montre cette nouvelle InsertProduct méthode en action :

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim new_productID As Integer = Convert.ToInt32(productsAdapter.InsertProduct( _
    "New Product", 1, 1, "12 tins per carton", 14.95, 10, 0, 10, false))
productsAdapter.Delete(new_productID)

Étape 5 : Fin de la couche d’accès aux données

Notez que la ProductsTableAdapters classe retourne les valeurs et SupplierID les CategoryID valeurs de la Products table, mais n’inclut pas la CategoryName colonne de la Categories table ou la CompanyName colonne de la Suppliers table, bien qu’il s’agit probablement des colonnes que nous voulons afficher lors de l’affichage des informations sur le produit. Nous pouvons augmenter la méthode initiale de TableAdapter, GetProducts()pour inclure à la fois les valeurs de colonne et CompanyName les CategoryName valeurs de colonne, qui mettent également à jour le DataTable fortement typé pour inclure ces nouvelles colonnes.

Cela peut poser un problème, cependant, car les méthodes de TableAdapter pour l’insertion, la mise à jour et la suppression de données sont basées sur cette méthode initiale. Heureusement, les méthodes générées automatiquement pour l’insertion, la mise à jour et la suppression ne sont pas affectées par les sous-requêtes de la SELECT clause. En prenant soin d’ajouter nos requêtes aux Categories sous-requêtes et Suppliers en tant que sous-requêtes, plutôt que JOIN celles-ci, nous éviterons d’avoir à retravailler ces méthodes pour modifier les données. Cliquez avec le bouton droit sur la GetProducts() méthode dans la ProductsTableAdapter méthode, puis choisissez Configurer. Ensuite, ajustez la SELECT clause pour qu’elle ressemble à ceci :

SELECT     ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM         Products

Mettre à jour l’instruction SELECT pour la méthode GetProducts()

Figure 29 : Mettre à jour l’instruction SELECT de la GetProducts() méthode (Click pour afficher l’image de taille complète)

Après avoir mis à jour la GetProducts() méthode pour utiliser cette nouvelle requête, DataTable inclut deux nouvelles colonnes : CategoryName et SupplierName.

DataTable products a deux nouvelles colonnes

Figure 30 : DataTable Products comporte deux nouvelles colonnes

Prenez un moment pour mettre à jour la SELECT clause dans la GetProductsByCategoryID(categoryID) méthode également.

Si vous mettez à jour la syntaxe à l’aide JOIN du GetProducts() SELECT Concepteur DataSet, vous ne pourrez pas générer automatiquement les méthodes d’insertion, de mise à jour et de suppression de données de base de données à l’aide du modèle direct de base de données. Au lieu de cela, vous devrez les créer manuellement comme nous l’avons fait avec la InsertProduct méthode précédemment dans ce tutoriel. En outre, vous devez fournir manuellement les InsertCommandvaleurs , UpdateCommandet DeleteCommand les valeurs de propriété si vous souhaitez utiliser le modèle de mise à jour par lots.

Ajout des TableAdapters restants

Jusqu’à présent, nous n’avons examiné que l’utilisation d’une table TableAdapter unique pour une seule table de base de données. Toutefois, la base de données Northwind contient plusieurs tables associées avec lesquelles nous devons travailler dans notre application web. Un DataSet typé peut contenir plusieurs DataTables associés. Par conséquent, pour terminer notre DAL, nous devons ajouter des DataTables pour les autres tables que nous utiliserons dans ces didacticiels. Pour ajouter un nouveau TableAdapter à un Jeu de données typé, ouvrez le Concepteur DataSet, cliquez avec le bouton droit dans le Concepteur, puis choisissez Ajouter /TableAdapter. Cela crée un DataTable et TableAdapter et vous guide tout au long de l’Assistant que nous avons examiné précédemment dans ce tutoriel.

Prenez quelques minutes pour créer les TablesAdapters et méthodes suivantes à l’aide des requêtes suivantes. Notez que les requêtes de la ProductsTableAdapter sous-requête incluent les sous-requêtes pour saisir les noms de la catégorie et des fournisseurs de chaque produit. En outre, si vous avez suivi, vous avez déjà ajouté les méthodes et GetProductsByCategoryID(categoryID) les méthodes de GetProducts() la ProductsTableAdapter classe.

  • ProductsTableAdapter

    • GetProducts :

      SELECT     ProductID, ProductName, SupplierID, 
      CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, 
      UnitsOnOrder, ReorderLevel, Discontinued, 
      (SELECT CategoryName FROM Categories WHERE
      Categories.CategoryID = Products.CategoryID) as 
      CategoryName, (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      
    • GetProductsByCategoryID :

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName,
      (SELECT CompanyName FROM Suppliers WHERE
      Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM         Products
      WHERE      CategoryID = @CategoryID
      
    • GetProductsBySupplierID :

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE 
      Suppliers.SupplierID = Products.SupplierID) as SupplierName
      FROM         Products
      WHERE SupplierID = @SupplierID
      
    • GetProductByProductID :

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName 
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      WHERE ProductID = @ProductID
      
  • CategoriesTableAdapter

    • GetCategories :

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      
    • GetCategoryByCategoryID :

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      WHERE CategoryID = @CategoryID
      
  • SuppliersTableAdapter

    • GetSuppliers :

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      
    • GetSuppliersByCountry :

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE Country = @Country
      
    • GetSupplierBySupplierID :

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE SupplierID = @SupplierID
      
  • EmployeesTableAdapter

    • GetEmployees :

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      
    • GetEmployeesByManager :

      SELECT     EmployeeID, LastName, FirstName, Title, 
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE ReportsTo = @ManagerID
      
    • GetEmployeeByEmployeeID :

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE EmployeeID = @EmployeeID
      

Concepteur DataSet après l’ajout des quatre TableAdapters

Figure 31 : Concepteur DataSet après l’ajout des quatre TableAdapters (cliquez pour afficher l’image de taille complète)

Ajout de code personnalisé à la dal

Les TableAdapters et DataTables ajoutés au DataSet typé sont exprimés sous la forme d’un fichier de définition de schéma XML (Northwind.xsd). Vous pouvez afficher ces informations de schéma en cliquant avec le bouton droit sur le fichier dans le Explorateur de solutions et en choisissant Afficher le Northwind.xsd code.

Fichier XSD (XML Schema Definition) pour l’ensemble de données typé Northwinds

Figure 32 : Fichier XSD (XML Schema Definition) pour l’ensemble de données typé Northwinds (Cliquez pour afficher l’image de taille complète)

Ces informations de schéma sont traduites en code C# ou Visual Basic au moment du design lors de la compilation ou au moment de l’exécution (si nécessaire), à quel moment vous pouvez le parcourir avec le débogueur. Pour afficher ce code généré automatiquement, accédez à l’affichage de classes et explorez les classes TableAdapter ou Typed DataSet. Si vous ne voyez pas l’affichage classe sur votre écran, accédez au menu Affichage et sélectionnez-le à partir de là, ou appuyez sur Ctrl+Maj+C. À partir de l’affichage de classes, vous pouvez voir les propriétés, les méthodes et les événements des classes Typed DataSet et TableAdapter. Pour afficher le code d’une méthode particulière, double-cliquez sur le nom de la méthode dans l’affichage de classes ou cliquez dessus avec le bouton droit, puis choisissez Atteindre la définition.

Inspecter le code généré automatiquement en sélectionnant Atteindre la définition à partir de l’affichage de classes

Figure 33 : Inspecter le code généré automatiquement en sélectionnant Atteindre la définition dans l’affichage de classes

Même si le code généré automatiquement peut être un excellent économiseur de temps, le code est souvent très générique et doit être personnalisé pour répondre aux besoins uniques d’une application. Toutefois, le risque d’étendre le code généré automatiquement est que l’outil qui a généré le code peut décider qu’il est temps de « régénérer » et de remplacer vos personnalisations. Avec le nouveau concept de classe partielle de .NET 2.0, il est facile de fractionner une classe sur plusieurs fichiers. Cela nous permet d’ajouter nos propres méthodes, propriétés et événements aux classes générées automatiquement sans avoir à vous soucier de l’écriture de nos personnalisations par Visual Studio.

Pour montrer comment personnaliser le DAL, nous allons ajouter une GetProducts() méthode à la SuppliersRow classe. La SuppliersRow classe représente un enregistrement unique dans la Suppliers table ; chaque fournisseur peut fournir zéro à de nombreux produits. Il retourne donc GetProducts() ces produits du fournisseur spécifié. Pour ce faire, créez un fichier de classe dans le App_Code dossier nommé SuppliersRow.vb et ajoutez le code suivant :

Imports NorthwindTableAdapters
Partial Public Class Northwind
    Partial Public Class SuppliersRow
        Public Function GetProducts() As Northwind.ProductsDataTable
            Dim productsAdapter As New ProductsTableAdapter
            Return productsAdapter.GetProductsBySupplierID(Me.SupplierID)
        End Function
    End Class
End Class

Cette classe partielle indique au compilateur que lors de la génération de la Northwind.SuppliersRow classe pour inclure la GetProducts() méthode que nous venons de définir. Si vous générez votre projet, puis revenez à l’affichage de classes que vous verrez GetProducts() maintenant répertorié comme méthode Northwind.SuppliersRow.

La méthode GetProducts() fait maintenant partie de la classe Northwind.SuppliersRow

Figure 34 : La GetProducts() méthode fait maintenant partie de la Northwind.SuppliersRow classe

La GetProducts() méthode peut maintenant être utilisée pour énumérer l’ensemble de produits d’un fournisseur particulier, comme le montre le code suivant :

Dim suppliersAdapter As New NorthwindTableAdapters.SuppliersTableAdapter()
Dim suppliers As Northwind.SuppliersDataTable = suppliersAdapter.GetSuppliers()
For Each supplier As Northwind.SuppliersRow In suppliers
    Response.Write("Supplier: " & supplier.CompanyName)
    Response.Write("<ul>")
    Dim products As Northwind.ProductsDataTable = supplier.GetProducts()
    For Each product As Northwind.ProductsRow In products
        Response.Write("<li>" & product.ProductName & "</li>")
    Next
    Response.Write("</ul><p> </p>")
Next

Ces données peuvent également être affichées dans n’importe quel ASP. Contrôles Web de données de NET. La page suivante utilise un contrôle GridView avec deux champs :

  • BoundField qui affiche le nom de chaque fournisseur et
  • TemplateField qui contient un contrôle BulletedList lié aux résultats retournés par la GetProducts() méthode pour chaque fournisseur.

Nous allons examiner comment afficher ces rapports maître-détail dans les didacticiels futurs. Pour l’instant, cet exemple est conçu pour illustrer l’utilisation de la méthode personnalisée ajoutée à la Northwind.SuppliersRow classe.

SuppliersAndProducts.aspx

<%@ Page Language="VB" CodeFile="SuppliersAndProducts.aspx.vb"
    AutoEventWireup="true" Inherits="SuppliersAndProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            Suppliers and Their Products</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             AutoGenerateColumns="False"
             CssClass="DataWebControlStyle">
                <HeaderStyle CssClass="HeaderStyle" />
                <AlternatingRowStyle CssClass="AlternatingRowStyle" />
                <Columns>
                    <asp:BoundField DataField="CompanyName"
                      HeaderText="Supplier" />
                    <asp:TemplateField HeaderText="Products">
                        <ItemTemplate>
                            <asp:BulletedList ID="BulletedList1"
                             runat="server" DataSource="<%# CType(CType(Container.DataItem, System.Data.DataRowView).Row, Northwind.SuppliersRow).GetProducts() %>"
                                 DataTextField="ProductName">
                            </asp:BulletedList>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

SuppliersAndProducts.aspx.vb

Imports NorthwindTableAdapters
Partial Class SuppliersAndProducts
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim suppliersAdapter As New SuppliersTableAdapter
        GridView1.DataSource = suppliersAdapter.GetSuppliers()
        GridView1.DataBind()
    End Sub
End Class

Le nom de la société du fournisseur est répertorié dans la colonne gauche, leurs produits à droite

Figure 35 : Le nom de la société du fournisseur est répertorié dans la colonne gauche, leurs produits dans la droite (cliquez pour afficher l’image de taille complète)

Résumé

Lors de la création d’une application web créant le DAL doit être l’une de vos premières étapes, se produisant avant de commencer à créer votre couche de présentation. Avec Visual Studio, la création d’un DAL basé sur des jeux de données typés est une tâche qui peut être effectuée en 10 à 15 minutes sans écrire de ligne de code. Les didacticiels en cours s’appuient sur ce DAL. Dans le tutoriel suivant, nous allons définir un certain nombre de règles métier et voir comment les implémenter dans une couche logique métier distincte.

Bonne programmation !

Pour aller plus loin

Pour plus d’informations sur les sujets abordés dans ce tutoriel, consultez les ressources suivantes :

Formation vidéo sur les rubriques contenues dans ce didacticiel

À 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 Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez et Carlos Santos. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.