Partager via


Utilisation de dépendances de cache SQL (VB)

par Scott Mitchell

Télécharger le PDF

La stratégie de mise en cache la plus simple consiste à autoriser l’expiration des données mises en cache après une période spécifiée. Toutefois, cette approche simple signifie que les données mises en cache ne conservent aucune association avec sa source de données sous-jacente, ce qui entraîne des données obsolètes qui sont conservées trop longtemps ou des données actuelles qui ont expiré trop tôt. Une meilleure approche consiste à utiliser la classe SqlCacheDependency afin que les données restent mises en cache jusqu’à ce que ses données sous-jacentes soient modifiées dans la base de données SQL. Ce tutoriel vous montre comment procéder.

Présentation

Les techniques de mise en cache examinées dans les didacticiels Caching Data with the ObjectDataSource et Caching Data in the Architecture ont utilisé une expiration basée sur le temps pour supprimer les données du cache après une période spécifiée. Cette approche est le moyen le plus simple d’équilibrer les gains de performances de la mise en cache par rapport à l’obsolescence des données. En sélectionnant une expiration de temps de x secondes, un développeur de pages reconnaît profiter des avantages de la mise en cache pendant seulement x secondes, mais peut se reposer facilement que ses données ne seront jamais obsolètes plus d’un maximum de x secondes. Bien entendu, pour les données statiques, x peut être étendu à la durée de vie de l’application web, comme nous l’avons examiné dans le didacticiel de mise en cache des données au démarrage de l’application .

Lors de la mise en cache des données de base de données, une expiration basée sur le temps est souvent choisie pour sa facilité d’utilisation, mais elle est souvent une solution insuffisante. Dans l’idéal, les données de base de données restent mises en cache tant que les données sous-jacentes n’ont pas été modifiées dans la base de données ; alors seulement le cache serait supprimé. Cette approche optimise les avantages en matière de performances de la mise en cache et réduit la durée des données obsolètes. Toutefois, pour profiter de ces avantages, il doit y avoir un système en place qui sait quand les données de base de données sous-jacentes ont été modifiées et supprime les éléments correspondants du cache. Avant ASP.NET 2.0, les développeurs de pages étaient responsables de l’implémentation de ce système.

ASP.NET 2.0 fournit une SqlCacheDependency classe et l’infrastructure nécessaire pour déterminer quand une modification s’est produite dans la base de données afin que les éléments mis en cache correspondants puissent être supprimés. Il existe deux techniques pour déterminer quand les données sous-jacentes ont changé : la notification et l’interrogation. Après avoir discuté des différences entre la notification et l’interrogation, nous allons créer l’infrastructure nécessaire pour prendre en charge l’interrogation, puis explorer comment utiliser la SqlCacheDependency classe dans des scénarios déclaratifs et programmatiquement.

Comprendre la notification et l’interrogation

Il existe deux techniques qui peuvent être utilisées pour déterminer quand les données d’une base de données ont été modifiées : notification et interrogation. Avec la notification, la base de données avertit automatiquement le runtime ASP.NET lorsque les résultats d’une requête particulière ont été modifiés depuis la dernière exécution de la requête, à quel point les éléments mis en cache associés à la requête sont supprimés. Grâce au sondage, le serveur de base de données conserve des informations sur le moment où certaines tables ont été mises à jour pour la dernière fois. Le runtime ASP.NET interroge régulièrement la base de données pour vérifier les tables qui ont changé depuis leur entrée dans le cache. Ces tables dont les données ont été modifiées ont leurs éléments de cache associés évincés.

L’option de notification nécessite moins de configuration que l’interrogation et est plus granulaire, car elle effectue le suivi des modifications au niveau de la requête plutôt qu’au niveau de la table. Malheureusement, les notifications ne sont disponibles que dans les éditions complètes de Microsoft SQL Server 2005 (c’est-à-dire les éditions non Express). Toutefois, l’option d’interrogation peut être utilisée pour toutes les versions de Microsoft SQL Server de 7.0 à 2005. Étant donné que ces didacticiels utilisent l’édition Express de SQL Server 2005, nous allons nous concentrer sur la configuration et l’utilisation de l’option d’interrogation. Consultez la section Autres lectures à la fin de ce tutoriel pour obtenir d’autres ressources sur les fonctionnalités de notification de SQL Server 2005.

Avec l’interrogation, la base de données doit être configurée pour inclure une table nommée AspNet_SqlCacheTablesForChangeNotification qui comporte trois colonnes : tableName, notificationCreatedet changeId. Cette table contient une ligne pour chaque table qui a des données qui peuvent avoir besoin d’être utilisées dans une dépendance de cache SQL dans l’application web. La tableName colonne spécifie le nom de la table, tandis que notificationCreated la date et l’heure à laquelle la ligne a été ajoutée à la table. La changeId colonne est de type int et a une valeur initiale de 0. Sa valeur est incrémentée avec chaque modification apportée à la table.

En plus de la AspNet_SqlCacheTablesForChangeNotification table, la base de données doit également inclure des déclencheurs sur chacune des tables qui peuvent apparaître dans une dépendance de cache SQL. Ces déclencheurs sont exécutés chaque fois qu’une ligne est insérée, mise à jour ou supprimée et incrémentent la valeur de changeId de la table dans AspNet_SqlCacheTablesForChangeNotification.

Le runtime ASP.NET suit l'état actuel changeId d'une table lors du cache des données avec un objet SqlCacheDependency. La base de données est régulièrement vérifiée et tous les SqlCacheDependency objets dont changeId la valeur diffère de la base de données sont supprimés, car une valeur différente changeId indique qu’une modification a été apportée à la table depuis que les données ont été mises en cache.

Étape 1 : Exploration duaspnet_regsql.exeprogramme de ligne de commande

Avec l’approche d’interrogation, la base de données doit être configurée pour contenir l’infrastructure décrite ci-dessus : une table prédéfinie (AspNet_SqlCacheTablesForChangeNotification), une poignée de procédures stockées et des déclencheurs sur chacune des tables qui peuvent être utilisées dans les dépendances de cache SQL dans l’application web. Ces tables, procédures stockées et déclencheurs peuvent être créés via le programme aspnet_regsql.exede ligne de commande, qui se trouve dans le $WINDOWS$\Microsoft.NET\Framework\version dossier. Pour créer la AspNet_SqlCacheTablesForChangeNotification table et les procédures stockées associées, exécutez ce qui suit à partir de la ligne de commande :

/* For SQL Server authentication... */
aspnet_regsql.exe -S server -U user -P password -d database -ed
/* For Windows Authentication... */
aspnet_regsql.exe -S server -E -d database -ed

Remarque

Pour exécuter ces commandes, la connexion de base de données spécifiée doit appartenir aux rôles db_securityadmin et db_ddladmin.

Par exemple, pour ajouter l’infrastructure pour l’interrogation à une base de données Microsoft SQL Server nommée pubs sur un serveur de base de données nommé ScottsServer avec l’authentification Windows, accédez au répertoire approprié et, à partir de la ligne de commande, entrez :

aspnet_regsql.exe -S ScottsServer -E -d pubs -ed

Une fois l’infrastructure au niveau de la base de données ajoutée, nous devons ajouter les déclencheurs à ces tables qui seront utilisées dans les dépendances du cache SQL. Réutilisez le programme en ligne de commande aspnet_regsql.exe, mais spécifiez le nom de la table à l’aide du commutateur -t et, au lieu d’utiliser le commutateur -ed, utilisez -et, comme suit :

/* For SQL Server authentication... */
aspnet_regsql.exe -S <i>server</i>
-U <i>user</i> -P <i>password</i> -d <i>database</i> -t <i>tableName</i> -et
/* For Windows Authentication... */
aspnet_regsql.exe -S <i>server</i>
-E -d <i>database</i> -t <i>tableName</i> -et

Pour ajouter les déclencheurs aux tables authors et titles de la base de données pubs sur ScottsServer, utilisez :

aspnet_regsql.exe -S ScottsServer -E -d pubs -t authors -et
aspnet_regsql.exe -S ScottsServer -E -d pubs -t titles -et

Pour ce tutoriel, ajoutez les déclencheurs aux tableaux Products, Categories et Suppliers. Nous allons examiner la syntaxe de ligne de commande particulière à l’étape 3.

Étape 2 : Référencement d’une base de données Microsoft SQL Server 2005 Express Edition dansApp_Data

Le aspnet_regsql.exe programme de ligne de commande nécessite le nom de la base de données et du serveur pour ajouter l’infrastructure d’interrogation nécessaire. Mais quel est le nom de la base de données et du serveur d’une base de données Microsoft SQL Server 2005 Express qui réside dans le App_Data dossier ? Au lieu de devoir découvrir les noms de base de données et de serveurs, j’ai constaté que l’approche la plus simple consiste à attacher la base de données à l’instance localhost\SQLExpress de base de données et à renommer les données à l’aide de SQL Server Management Studio. Si vous disposez de l’une des versions complètes de SQL Server 2005 installées sur votre ordinateur, vous avez probablement déjà installé SQL Server Management Studio sur votre ordinateur. Si vous ne disposez que de l’édition Express, vous pouvez télécharger gratuitement Microsoft SQL Server Management Studio.

Commencez par fermer Visual Studio. Ensuite, ouvrez SQL Server Management Studio et choisissez de vous connecter au serveur à l’aide de l’authentification localhost\SQLExpress Windows.

Se connecter au serveur localhost\SQLExpress

Figure 1 : Attacher au localhost\SQLExpress serveur

Après la connexion au serveur, Management Studio affiche le serveur et dispose de sous-dossiers pour les bases de données, la sécurité, etc. Cliquez avec le bouton droit sur le dossier Bases de données et choisissez l’option Attacher. La boîte de dialogue Attacher des bases de données s’affiche (voir la figure 2). Cliquez sur le bouton Ajouter et sélectionnez le NORTHWND.MDF dossier de base de données dans le dossier de App_Data votre application web.

Attacher la base de données NORTHWND.MDF depuis le dossier App_Data

Figure 2 : Attacher la NORTHWND.MDF base de données à partir du App_Data dossier (cliquez pour afficher l’image de taille complète)

Cette opération ajoute la base de données au dossier Bases de données. Le nom de la base de données peut être le chemin complet du fichier de base de données ou le chemin d’accès complet précédé d’un GUID. Pour éviter d’avoir à taper ce nom de base de données long lors de l’utilisation de l’outil en ligne de commande aspnet_regsql.exe, renommez la base de données en un nom plus convivial en cliquant avec le bouton droit sur la base de données simplement attachée et en choisissant Renommer. J’ai renommé ma base de données en DataTutorials .

Renommer la base de données jointe en un nom plus proche de Human-Friendly

Figure 3 : Renommer la base de données jointe pour utiliser un nom plus approprié Human-Friendly.

Étape 3 : Ajout de l’infrastructure d’interrogation à la base de données Northwind

Maintenant que nous avons attachée la NORTHWND.MDF base de données depuis le App_Data dossier, nous sommes prêts à ajouter l’infrastructure de sondage. En supposant que vous avez renommé la base de données en DataTutorials, exécutez les quatre commandes suivantes :

aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -ed
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Products -et
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Categories -et
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Suppliers -et

Après avoir exécuté ces quatre commandes, cliquez avec le bouton droit sur le nom de la base de données dans Management Studio, accédez au sous-menu Tâches, puis choisissez Détacher. Fermez Ensuite Management Studio et rouvrez Visual Studio.

Une fois que Visual Studio a rouvert, explorez la base de données via l’Explorateur de serveurs. Notez la nouvelle table (AspNet_SqlCacheTablesForChangeNotification), les nouvelles procédures stockées et les déclencheurs sur les tables Products, Categories et Suppliers.

La base de données inclut désormais l’infrastructure d’interrogation nécessaire

Figure 4 : La base de données inclut désormais l’infrastructure d’interrogation nécessaire

Étape 4 : Configuration du service d’interrogation

Après avoir créé les tables, déclencheurs et procédures stockées nécessaires dans la base de données, l’étape finale consiste à configurer le service d’interrogation, qui est effectué en Web.config spécifiant les bases de données à utiliser et la fréquence d’interrogation en millisecondes. Le balisage suivant interroge la base de données Northwind une fois par seconde.

<?xml version="1.0"?>
<configuration>
   <connectionStrings>
      <add name="NORTHWNDConnectionString" connectionString=
          "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;
           Integrated Security=True;User Instance=True" 
           providerName="System.Data.SqlClient"/>
   </connectionStrings>
   <system.web>
      ...
      <!-- Configure the polling service used for SQL cache dependencies -->
      <caching>
         <sqlCacheDependency enabled="true" pollTime="1000" >
            <databases>
               <add name="NorthwindDB" 
                    connectionStringName="NORTHWNDConnectionString" />
            </databases>
         </sqlCacheDependency>
      </caching>
   </system.web>
</configuration>

La name valeur de l’élément <add> (NorthwindDB) associe un nom lisible par l’homme à une base de données particulière. Lors de l’utilisation des dépendances de cache SQL, nous devons faire référence au nom de la base de données défini ici, ainsi qu’à la table sur laquelle les données mises en cache sont basées. Nous verrons comment utiliser la classe SqlCacheDependency pour associer des dépendances de cache SQL aux données mises en cache par programmation à l’étape 6.

Une fois qu’une dépendance de cache SQL a été établie, le système d’interrogation se connecte aux bases de données définies dans les <databases> éléments toutes les pollTime millisecondes et exécute la AspNet_SqlCachePollingStoredProcedure procédure stockée. Cette procédure stockée qui a été ajoutée à l’étape 3 à l’aide de l'outil de ligne de commande aspnet_regsql.exe retourne les valeurs tableName et changeId de chaque enregistrement dans AspNet_SqlCacheTablesForChangeNotification. Les dépendances de cache SQL obsolètes sont supprimées du cache.

Le pollTime paramètre introduit un compromis entre les performances et l’obsolescence des données. Une petite pollTime valeur augmente le nombre de demandes adressées à la base de données, mais supprime plus rapidement les données obsolètes du cache. Une valeur plus grande pollTime réduit le nombre de demandes de base de données, mais augmente le délai entre le moment où les données principales changent et lorsque les éléments de cache associés sont supprimés. Heureusement, la demande de base de données exécute une procédure stockée simple qui retourne quelques lignes à partir d’une table simple et légère. Mais faites des expériences avec différentes pollTime valeurs pour trouver un équilibre idéal entre l’accès à la base de données et l’obsolescence des données pour votre application. La plus pollTime petite valeur autorisée est 500.

Remarque

L’exemple ci-dessus fournit une valeur unique pollTime dans l’élément <sqlCacheDependency> , mais vous pouvez éventuellement spécifier la pollTime valeur dans l’élément <add> . Cela est utile si vous avez plusieurs bases de données spécifiées et souhaitez personnaliser la fréquence d’interrogation par base de données.

Étape 5 : Utilisation déclarative des dépendances du cache SQL

Dans les étapes 1 à 4, nous avons examiné comment configurer l’infrastructure de base de données nécessaire et configurer le système d’interrogation. Avec cette infrastructure en place, nous pouvons maintenant ajouter des éléments au cache de données avec une dépendance de cache SQL associée à l’aide de techniques programmatiques ou déclaratives. Dans cette étape, nous allons examiner comment utiliser de manière déclarative les dépendances de cache SQL. À l’étape 6, nous allons examiner l’approche programmatique.

Le didacticiel Sur la mise en cache des données avec ObjectDataSource a exploré les fonctionnalités de mise en cache déclaratives de ObjectDataSource. En définissant simplement la EnableCaching propriété sur True et la CacheDuration propriété sur un intervalle de temps, ObjectDataSource met automatiquement en cache les données retournées par son objet sous-jacent pour l’intervalle spécifié. ObjectDataSource peut également utiliser une ou plusieurs dépendances de cache SQL.

Pour illustrer l’utilisation des dépendances de cache SQL de manière déclarative, ouvrez la SqlCacheDependencies.aspx page dans le Caching dossier et faites glisser un GridView à partir de la boîte à outils vers le Concepteur. Définissez gridView s ID sur ProductsDeclarative et, à partir de sa balise active, choisissez de le lier à un nouvel ObjectDataSource nommé ProductsDataSourceDeclarative.

Créer un objet ObjectDataSource nommé ProductsDataSourceDeclarative

Figure 5 : Créer une nouvelle propriété ObjectDataSource nommée ProductsDataSourceDeclarative (cliquez pour afficher l’image de taille complète)

Configurez l'ObjectDataSource pour utiliser la classe ProductsBLL et définissez la liste déroulante sur GetProducts() sous l’onglet SELECT. Dans l’onglet UPDATE, choisissez la UpdateProduct surcharge avec trois paramètres d’entrée : productName, unitPriceet productID. Définissez les listes déroulantes sur (Aucun) dans les onglets INSERT et DELETE.

Utilisez la surcharge UpdateProduct avec trois paramètres d'entrée

Figure 6 : Utiliser la surcharge UpdateProduct avec trois paramètres d’entrée (cliquez pour afficher l’image en taille réelle)

Définissez la liste Drop-Down sur (Aucun) pour les onglets INSERT et DELETE

Figure 7 : Définir la liste Drop-Down sur (Aucun) pour les onglets INSERT et DELETE (cliquez pour afficher l’image de taille complète)

Une fois l’Assistant Configuration de la source de données terminé, Visual Studio crée des BoundFields et des CheckBoxFields dans GridView pour chacun des champs de données. Supprimez tous les champs, sauf ProductName, CategoryName et UnitPrice, et formatez ces champs à votre convenance. À partir de la balise intelligente GridView, cochez les cases Activer la pagination, Activer le tri et Activer la modification. Visual Studio affectera la propriété de ObjectDataSource à OldValuesParameterFormatStringoriginal_{0}. Pour que la fonctionnalité de modification de GridView fonctionne correctement, supprimez entièrement cette propriété de la syntaxe déclarative ou remettez-la sur sa valeur par défaut. {0}

Enfin, ajoutez un contrôle Label Web au-dessus de GridView et définissez sa propriété ID sur ODSEvents et sa propriété EnableViewState sur False. Après avoir apporté ces modifications, le balisage déclaratif de votre page doit ressembler à ce qui suit. Notez que j’ai apporté un certain nombre de personnalisations esthétiques aux champs GridView qui ne sont pas nécessaires pour illustrer la fonctionnalité de dépendance du cache SQL.

<asp:Label ID="ODSEvents" runat="server" EnableViewState="False" />
<asp:GridView ID="ProductsDeclarative" runat="server" 
    AutoGenerateColumns="False" DataKeyNames="ProductID" 
    DataSourceID="ProductsDataSourceDeclarative" 
    AllowPaging="True" AllowSorting="True">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
            <EditItemTemplate>
                <asp:TextBox ID="ProductName" runat="server" 
                    Text='<%# Bind("ProductName") %>' />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
                    ControlToValidate="ProductName" Display="Dynamic" 
                    ErrorMessage="You must provide a name for the product." 
                    SetFocusOnError="True"
                    runat="server">*</asp:RequiredFieldValidator>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" 
                    Text='<%# Bind("ProductName") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
            <EditItemTemplate>
                $<asp:TextBox ID="UnitPrice" runat="server" Columns="8" 
                    Text='<%# Bind("UnitPrice", "{0:N2}") %>'></asp:TextBox>
                <asp:CompareValidator ID="CompareValidator1" runat="server" 
                    ControlToValidate="UnitPrice"
                    ErrorMessage="You must enter a valid currency value with 
                        no currency symbols. Also, the value must be greater than 
                        or equal to zero."
                    Operator="GreaterThanEqual" SetFocusOnError="True" 
                    Type="Currency" Display="Dynamic" 
                    ValueToCompare="0">*</asp:CompareValidator>
            </EditItemTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" 
                    Text='<%# Bind("UnitPrice", "{0:c}") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSourceDeclarative" runat="server" 
    SelectMethod="GetProducts" TypeName="ProductsBLL" 
    UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Ensuite, créez un gestionnaire d’événements pour l’événement ObjectDataSource Selecting et ajoutez le code suivant :

Protected Sub ProductsDataSourceDeclarative_Selecting _
    (sender As Object, e As ObjectDataSourceSelectingEventArgs) _
    Handles ProductsDataSourceDeclarative.Selecting
    ODSEvents.Text = "-- Selecting event fired"
End Sub

Rappelez-vous que l’événement ObjectDataSource Selecting se déclenche uniquement lors de la récupération des données de son objet sous-jacent. Si ObjectDataSource accède aux données à partir de son propre cache, cet événement n’est pas déclenché.

À présent, visitez cette page via un navigateur. Étant donné que nous n’avons pas encore implémenté de mise en cache, chaque fois que vous pagez, triez ou modifiez la grille, la page doit afficher le texte « Sélection de l’événement déclenché, comme l’illustre la figure 8.

L’événement de sélection d’ObjectDataSource se déclenche chaque fois que gridView est paginé, modifié ou trié

Figure 8 : L’événement ObjectDataSource Selecting se déclenche chaque fois que gridView est paginé, modifié ou trié (cliquez pour afficher l’image de taille complète)

Comme nous l'avons vu dans le didacticiel La mise en cache des données avec ObjectDataSource, définir la propriété EnableCaching à True provoque la mise en cache des données par ObjectDataSource pendant la durée spécifiée par sa propriété CacheDuration. ObjectDataSource a également une SqlCacheDependency propriété, qui ajoute une ou plusieurs dépendances de cache SQL aux données mises en cache à l’aide du modèle :

databaseName1:tableName1;databaseName2:tableName2;...

databaseName est le nom de la base de données tel que spécifié dans l’attribut name de l’élément <add> dans Web.config, et tableName est le nom de la table de base de données. Par exemple, pour créer un ObjectDataSource qui met en cache les données indéfiniment en fonction d’une dépendance de cache SQL sur la table Northwind Products , définissez la propriété ObjectDataSource EnableCaching sur True et sa SqlCacheDependency propriété sur NorthwindDB :Products.

Remarque

Vous pouvez utiliser une dépendance de cache SQL et une expiration basée sur le temps en définissant EnableCaching à True, CacheDuration sur l’intervalle de temps, et SqlCacheDependency sur le nom de la base de données et des tables. ObjectDataSource supprime ses données lorsque l’expiration basée sur le temps est atteinte ou lorsque le système d’interrogation note que les données de base de données sous-jacentes ont changé, selon ce qui se produit en premier.

GridView dans SqlCacheDependencies.aspx affiche les données de deux tables - Products et Categories (le champ produit CategoryName est récupéré via un JOIN sur Categories). Par conséquent, nous voulons spécifier deux dépendances de cache SQL : NorthwindDB :Products ; NorthwindDB :Categories .

Configurer ObjectDataSource pour prendre en charge la mise en cache à l’aide des dépendances de cache SQL sur les produits et les catégories

Figure 9 : Configurer l'ObjectDataSource pour prendre en charge la mise en cache à l'aide des dépendances de cache SQL sur Products et Categories (Cliquez pour afficher l’image en taille réelle)

Après avoir configuré ObjectDataSource pour prendre en charge la mise en cache, revisitez la page via un navigateur. Là encore, le texte « Sélection de l’événement déclenché doit apparaître sur la première visite de page, mais doit disparaître lors de la pagination, du tri ou du clic sur les boutons Modifier ou Annuler. Cela est dû au fait qu’une fois les données chargées dans le cache ObjectDataSource, elles restent là jusqu’à ce que les ProductsCategories tables soient modifiées ou que les données soient mises à jour via GridView.

Après avoir parcouru la grille et noté l'absence du texte « Événement de sélection déclenché », ouvrez une nouvelle fenêtre de navigateur et accédez au didacticiel des bases dans la section Édition, Insertion et Suppression (~/EditInsertDelete/Basics.aspx). Mettez à jour le nom ou le prix d’un produit. Ensuite, à partir de la première fenêtre du navigateur, affichez une autre page de données, triez la grille ou cliquez sur le bouton Modifier d’une ligne. Cette fois, l'événement « Selecting » a été déclenché et devrait réapparaître, car les données de la base de données sous-jacente ont été modifiées (voir la figure 10). Si le texte n’apparaît pas, attendez quelques instants et réessayez. N’oubliez pas que le service d’interrogation recherche les modifications apportées à la Products table toutes les pollTime millisecondes. Par conséquent, il existe un délai entre le moment où les données sous-jacentes sont mises à jour et lorsque les données mises en cache sont supprimées.

La modification de la table Produits supprime les données de produit mises en cache

Figure 10: Modification de la table des produits expulse les données de produit mises en cache (Cliquez pour afficher l’image pleine taille)

Étape 6 : Utilisation par programmation de laSqlCacheDependencyclasse

Le didacticiel Sur la mise en cache des données dans l’architecture a examiné les avantages de l’utilisation d’une couche de mise en cache distincte dans l’architecture, par opposition au couplage étroit de la mise en cache avec ObjectDataSource. Dans ce tutoriel, nous avons créé une ProductsCL classe pour illustrer par programmation l’utilisation du cache de données. Pour utiliser les dépendances de cache SQL dans la couche de mise en cache, utilisez la SqlCacheDependency classe.

Avec le système d’interrogation, un SqlCacheDependency objet doit être associé à une paire de base de données et de table particulière. Le code suivant, par exemple, crée un SqlCacheDependency objet basé sur la table de base de Products données Northwind :

Dim productsTableDependency As _
    New Caching.SqlCacheDependency("NorthwindDB", "Products")

Les deux paramètres d’entrée du SqlCacheDependency constructeur sont respectivement les noms de base de données et de table. Comme avec la propriété ObjectDataSource SqlCacheDependency , le nom de la base de données utilisé est identique à la valeur spécifiée dans l’attribut name de l’élément <add> dans Web.config. Le nom de la table est le nom réel de la table de base de données.

Pour associer un SqlCacheDependency à un élément ajouté au cache de données, utilisez l'une des surcharges de méthode Insert qui accepte une dépendance. Le code suivant ajoute valeur au cache de données pour une durée indéfinie, mais l’associe avec un SqlCacheDependency sur la table Products. En bref, la valeur reste dans le cache jusqu’à ce qu’elle soit supprimée en raison de contraintes de mémoire ou parce que le système d’interrogation a détecté que la Products table a changé depuis qu’elle a été mise en cache.

Dim productsTableDependency As _
    New Caching.SqlCacheDependency("NorthwindDB", "Products")
Cache.Insert(key, _
             value, _ 
             productsTableDependency, _
             System.Web.Caching.Cache.NoAbsoluteExpiration, _
             System.Web.Caching.Cache.NoSlidingExpiration)

Actuellement, la classe Caching Layer ProductsCL met en cache les données de la table Products en utilisant une expiration temporelle de 60 secondes. Nous allons mettre à jour cette classe afin qu’elle utilise des dépendances de cache SQL à la place. La ProductsCL méthode s AddCacheItem de classe, qui est chargée d’ajouter les données au cache, contient actuellement le code suivant :

Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
    Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
    ' Make sure MasterCacheKeyArray(0) is in the cache - if not, add it
    If DataCache(MasterCacheKeyArray(0)) Is Nothing Then
        DataCache(MasterCacheKeyArray(0)) = DateTime.Now
    End If
    ' Add a CacheDependency
    Dim dependency As _
        New Caching.CacheDependency(Nothing, MasterCacheKeyArray)
    DataCache.Insert(GetCacheKey(rawKey), value, dependency, _
        DateTime.Now.AddSeconds(CacheDuration), _
        Caching.Cache.NoSlidingExpiration)
End Sub

Mettez à jour ce code pour utiliser un SqlCacheDependency objet au lieu de la dépendance de MasterCacheKeyArray cache :

Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
    Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
    ' Add the SqlCacheDependency objects for Products
    Dim productsTableDependency As New _
        Caching.SqlCacheDependency("NorthwindDB", "Products")
    DataCache.Insert(GetCacheKey(rawKey), value, productsTableDependency, _
        Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration)
End Sub

Pour tester cette fonctionnalité, ajoutez un GridView à la page sous le GridView existant ProductsDeclarative . Définissez ce nouveau GridView sur IDProductsProgrammatic et, par le biais de sa balise active, liez-le à un nouvel ObjectDataSource nommé ProductsDataSourceProgrammatic. Configurez ObjectDataSource pour utiliser la ProductsCL classe, en définissant les listes déroulantes dans les onglets SELECT et UPDATE, GetProducts respectivement UpdateProduct.

Configurer ObjectDataSource pour utiliser la classe ProductsCL

Figure 11 : Configurer ObjectDataSource pour utiliser la classe (ProductsCL de taille complète)

Sélectionnez la méthode GetProducts depuis la liste Drop-Down de l’onglet SELECT

Figure 12 : Sélectionner la GetProducts méthode dans la liste des Drop-Down de l’onglet SELECT (cliquez pour afficher l’image de taille complète)

Choisissez la méthode UpdateProduct dans la liste des Drop-Down de l’onglet UPDATE

Figure 13 : Choisir la méthode UpdateProduct dans la liste des Drop-Down de l’onglet UPDATE (cliquez pour afficher l’image de taille complète)

Une fois l’Assistant Configuration de la source de données terminé, Visual Studio crée des BoundFields et des CheckBoxFields dans GridView pour chacun des champs de données. Comme avec le premier GridView ajouté à cette page, supprimez tous les champs, sauf ProductName, CategoryName et UnitPrice, puis mettez en forme ces champs comme vous le souhaitez. À partir de la balise intelligente GridView, cochez les cases Activer la pagination, Activer le tri et Activer la modification. Comme avec ProductsDataSourceDeclarative ObjectDataSource, Visual Studio définit la propriété ProductsDataSourceProgrammatic de OldValuesParameterFormatStringObjectDataSource sur original_{0}. Pour que la fonctionnalité de modification de GridView fonctionne correctement, reconfigurez cette propriété à {0} (ou supprimez complètement l’affectation de propriété de la syntaxe déclarative).

Une fois ces tâches terminées, le balisage déclaratif GridView et ObjectDataSource résultant doit ressembler à ce qui suit :

<asp:GridView ID="ProductsProgrammatic" runat="server" 
    AutoGenerateColumns="False" DataKeyNames="ProductID" 
    DataSourceID="ProductsDataSourceProgrammatic" AllowPaging="True" 
    AllowSorting="True">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
            <EditItemTemplate>
                <asp:TextBox ID="ProductName" runat="server" 
                    Text='<%# Bind("ProductName") %>' />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1"  
                    ControlToValidate="ProductName" Display="Dynamic" 
                    ErrorMessage="You must provide a name for the product." 
                    SetFocusOnError="True"
                    runat="server">*</asp:RequiredFieldValidator>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" 
                    Text='<%# Bind("ProductName") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
            <EditItemTemplate>
                $<asp:TextBox ID="UnitPrice" runat="server" Columns="8" 
                    Text='<%# Bind("UnitPrice", "{0:N2}") %>'></asp:TextBox>
                <asp:CompareValidator ID="CompareValidator1" runat="server" 
                    ControlToValidate="UnitPrice" Display="Dynamic" 
                    ErrorMessage="You must enter a valid currency value with no 
                        currency symbols. Also, the value must be greater than 
                        or equal to zero."
                    Operator="GreaterThanEqual" SetFocusOnError="True" 
                    Type="Currency" ValueToCompare="0">*</asp:CompareValidator>
            </EditItemTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" 
                    Text='<%# Bind("UnitPrice", "{0:c}") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSourceProgrammatic" runat="server" 
    OldValuesParameterFormatString="{0}" SelectMethod="GetProducts" 
    TypeName="ProductsCL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Pour tester la dépendance de cache SQL dans la couche de mise en cache, définissez un point d’arrêt dans la méthode de la classe ProductCL, puis commencez le débogage. Lors de la première visite SqlCacheDependencies.aspx, le point d’arrêt doit être atteint lorsque les données sont demandées pour la première fois et placées dans le cache. Ensuite, accédez à une autre page dans GridView ou triez l’une des colonnes. Cela provoque GridView à réinterroger ses données, mais les données devraient se trouver dans le cache puisque la table de base de données Products n’a pas été modifiée. Si les données sont à plusieurs reprises introuvables dans le cache, assurez-vous qu’il y a suffisamment de mémoire disponible sur votre ordinateur et réessayez.

Après avoir paginé quelques pages de GridView, ouvrez une deuxième fenêtre de navigateur et accédez au didacticiel De base dans la section Édition, Insertion et Suppression (~/EditInsertDelete/Basics.aspx). Mettez à jour un enregistrement à partir de la table Products, puis, dans la première fenêtre du navigateur, affichez une nouvelle page ou cliquez sur l’un des en-têtes de tri.

Dans ce scénario, vous verrez l’une des deux choses suivantes : soit le point d’arrêt est atteint, indiquant que les données mises en cache ont été supprimées en raison de la modification de la base de données ; ou, le point d’arrêt n’est pas atteint, ce qui signifie qu’il SqlCacheDependencies.aspx affiche désormais des données obsolètes. Si le point d’arrêt n’est pas atteint, il est probable que le service d’interrogation n’a pas encore été activé après que les données ont été modifiées. N’oubliez pas que le service d’interrogation recherche les modifications apportées à la Products table toutes les pollTime millisecondes. Par conséquent, il existe un délai entre le moment où les données sous-jacentes sont mises à jour et lorsque les données mises en cache sont supprimées.

Remarque

Ce délai est plus susceptible d’apparaître lors de la modification de l’un des produits via GridView dans SqlCacheDependencies.aspx. Dans le didacticiel Sur la mise en cache des données dans l’architecture, nous avons ajouté la MasterCacheKeyArray dépendance de cache pour assurer que les données en cours d'édition via la méthode de la ProductsCL classe UpdateProduct ont été évincées du cache. Toutefois, nous avons remplacé cette dépendance de cache lors de la modification de la AddCacheItem méthode précédemment dans cette étape, et par conséquent, la ProductsCL classe continuera à afficher les données mises en cache jusqu’à ce que le système d’interrogation note la modification de la Products table. Nous allons voir comment réintroduire la dépendance de cache à l’étape MasterCacheKeyArray 7.

Étape 7 : Association de plusieurs dépendances à un élément mis en cache

Rappelez-vous que la dépendance de MasterCacheKeyArray cache est utilisée pour s’assurer que toutes les données liées au produit sont supprimées du cache lorsqu’un élément unique associé à celui-ci est mis à jour. Par exemple, la GetProductsByCategoryID(categoryID) méthode met en cache des ProductsDataTables instances pour chaque valeur categoryID unique. Si l’un de ces objets est supprimé, la MasterCacheKeyArray dépendance de cache garantit que les autres sont également supprimées. Sans cette dépendance de cache, lorsque les données mises en cache sont modifiées, il existe la possibilité que d’autres données de produit mises en cache soient obsolètes. Par conséquent, il est important que nous maintenons la dépendance de cache lors de l’utilisation MasterCacheKeyArray des dépendances de cache SQL. Toutefois, la méthode du cache de Insert données autorise uniquement un seul objet de dépendance.

En outre, lors de l’utilisation des dépendances de cache SQL, nous devrons peut-être associer plusieurs tables de base de données en tant que dépendances. Par exemple, le ProductsDataTable cache dans la ProductsCL classe contient les noms de catégorie et de fournisseur pour chaque produit, mais la AddCacheItem méthode utilise uniquement une dépendance sur Products. Dans ce cas, si l’utilisateur met à jour le nom d’une catégorie ou d’un fournisseur, les données de produit mises en cache restent dans le cache et sont obsolètes. Par conséquent, nous voulons rendre les données de produit mises en cache dépendantes non seulement de la table Products, mais également des tables Categories et Suppliers.

La AggregateCacheDependency classe fournit un moyen d’associer plusieurs dépendances à un élément de cache. Commencez par créer une AggregateCacheDependency instance. Ensuite, ajoutez l’ensemble de dépendances à l’aide de la AggregateCacheDependency méthode s Add . Ensuite, lors de l’insertion de l’élément dans le cache de données, transmettez l’instance AggregateCacheDependency. Lorsque l’une des dépendances de l’instance AggregateCacheDependency change, l’élément mis en cache est supprimé.

L’exemple suivant montre le code mis à jour pour la classe ProductsCL méthode AddCacheItem. La méthode crée la dépendance de cache MasterCacheKeyArray ainsi que les objets SqlCacheDependency pour les tables Products, Categories, et Suppliers. Elles sont toutes combinées en un seul AggregateCacheDependency objet nommé aggregateDependencies, qui est ensuite passé dans la Insert méthode.

Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
    Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
    ' Make sure MasterCacheKeyArray(0) is in the cache - if not, add it.
    If DataCache(MasterCacheKeyArray(0)) Is Nothing Then
        DataCache(MasterCacheKeyArray(0)) = DateTime.Now
    End If
    'Create the CacheDependency
    Dim masterCacheKeyDependency As _
        New Caching.CacheDependency(Nothing, MasterCacheKeyArray)
    ' Add the SqlCacheDependency objects for Products, Categories, and Suppliers
    Dim productsTableDependency As _
        New Caching.SqlCacheDependency("NorthwindDB", "Products")
    Dim categoriesTableDependency As _
        New Caching.SqlCacheDependency("NorthwindDB", "Categories")
    Dim suppliersTableDependency As _
        New Caching.SqlCacheDependency("NorthwindDB", "Suppliers")
    ' Create an AggregateCacheDependency
    Dim aggregateDependencies As New Caching.AggregateCacheDependency()
    aggregateDependencies.Add(masterCacheKeyDependency, productsTableDependency, _
        categoriesTableDependency, suppliersTableDependency)
    DataCache.Insert(GetCacheKey(rawKey), value, aggregateDependencies, _
        Caching.Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration)
End Sub

Testez ce nouveau code. Maintenant, les modifications apportées aux tableaux Products, Categories ou Suppliers provoquent l’expulsion des données mises en cache. En outre, la méthode de la classe ProductsCLUpdateProduct, appelée lors de la modification d’un produit via GridView, supprime la dépendance de cache MasterCacheKeyArray, ce qui entraîne l’éviction du cache ProductsDataTable et la nouvelle récupération des données lors de la requête suivante.

Remarque

Les dépendances de cache SQL peuvent également être utilisées avec la mise en cache de sortie. Pour une démonstration de cette fonctionnalité, consultez : Utilisation de ASP.NET mise en cache de sortie avec SQL Server.

Résumé

Lors de la mise en cache des données de base de données, les données restent idéalement dans le cache jusqu’à ce qu’elles ne sont pas modifiées dans la base de données. Avec ASP.NET 2.0, les dépendances de cache SQL peuvent être créées et utilisées dans des scénarios déclaratifs et programmatiques. L’un des défis de cette approche est de découvrir quand les données ont été modifiées. Les versions complètes de Microsoft SQL Server 2005 fournissent des fonctionnalités de notification qui peuvent alerter une application lorsqu’un résultat de requête a changé. Pour l’édition Express de SQL Server 2005 et les versions antérieures de SQL Server, un système d’interrogation doit être utilisé à la place. Heureusement, la configuration de l’infrastructure d’interrogation nécessaire est assez simple.

Bonne programmation !

Pour aller plus loin

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

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