Partager via


Utilisation de dépendances de cache SQL (C#)

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 leur 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 arrivent à expiration trop tôt. Une meilleure approche consiste à utiliser la classe SqlCacheDependency afin que les données restent mises en cache jusqu’à ce que leurs données sous-jacentes ont été modifiées dans la base de données SQL. Ce didacticiel vous explique les procédures.

Introduction

Les techniques de mise en cache examinées dans les didacticiels Mise en cache des données avec ObjectDataSource et Mise en cache des données dans architecture utilisaient 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 un délai d’expiration de x secondes, un développeur de pages concède profiter des avantages en matière de performances de la mise en cache pendant seulement x secondes, mais peut se reposer facilement sur le fait 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 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 leur facilité d’utilisation, mais il s’agit souvent d’une solution inadéquate. Dans l’idéal, les données de la base de données restent mises en cache jusqu’à ce que les données sous-jacentes ont été modifiées dans la base de données ; ce n’est qu’alors que 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 bénéficier 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 abordé les 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 programmatiques.

Présentation de la notification et de l’interrogation

Deux techniques peuvent être utilisées pour déterminer quand les données d’une base de données ont été modifiées : la notification et l’interrogation. Avec la notification, la base de données alerte automatiquement l’ASP.NET runtime lorsque les résultats d’une requête particulière ont été modifiés depuis la dernière exécution de la requête, auquel cas les éléments mis en cache associés à la requête sont supprimés. Avec l’interrogation, le serveur de base de données conserve des informations sur la date de la dernière mise à jour de tables particulières. Le runtime ASP.NET interroge régulièrement la base de données pour case activée les tables qui ont changé depuis leur entrée dans le cache. Les éléments de cache associés aux tables dont les données ont été modifiées sont supprimé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 tutoriels 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 Lecture supplémentaire à la fin de ce tutoriel pour obtenir des ressources supplémentaires sur les fonctionnalités de notification 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 contient des données pouvant ê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 qu’elle notificationCreated indique la date et l’heure d’ajout de la ligne à la table. La changeId colonne est de type int et a une valeur initiale de 0. Sa valeur est incrémentée à 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 la table dans AspNet_SqlCacheTablesForChangeNotification.

Le runtime ASP.NET effectue le suivi du actuel changeId pour une table lors de la mise en cache des données à l’aide d’un SqlCacheDependency objet . 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 table et les AspNet_SqlCacheTablesForChangeNotification procédures stockées associées, exécutez la commande suivante à 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

Notes

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

Par exemple, pour ajouter l’infrastructure d’interrogation à une base de données Microsoft SQL Server nommée pubs sur un serveur de base de données nommé ScottsServer à l’aide de 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 aux tables qui seront utilisées dans les dépendances de cache SQL. Utilisez à nouveau le aspnet_regsql.exe programme de ligne de commande, mais spécifiez le nom de la table à l’aide du -t commutateur et, au lieu d’utiliser le -ed commutateur, 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 authors tables et titles de la pubs base de données 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 Productstables , Categorieset 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 ? Plutôt que d’avoir à découvrir les noms de la base de données et du serveur, j’ai constaté que l’approche la plus simple consiste à attacher la base de données à la localhost\SQLExpress base de données instance et à renommer les données à l’aide de SQL Server Management Studio. Si l’une des versions complètes de SQL Server 2005 est installée sur votre ordinateur, vous avez probablement déjà SQL Server Management Studio installée sur votre ordinateur. Si vous n’avez que l’édition Express, vous pouvez télécharger gratuitement Microsoft SQL Server Management Studio Express Edition.

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.

Attacher au serveur localhost\SQLExpress

Figure 1 : Attacher au localhost\SQLExpress serveur

Une fois connecté au serveur, Management Studio affiche le serveur et a des 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 dossier de base de données dans le NORTHWND.MDF dossier de App_Data votre application web.

Attachez le NORTHWND. Base de données MDF à partir du dossier App_Data

Figure 2 : Attacher la NORTHWND.MDF base de données à partir du App_Data dossier (cliquer pour afficher l’image en taille réelle)

Cette opération ajoute la base de données au dossier Databases. Le nom de la base de données peut être le chemin d’accès complet au fichier de base de données ou le chemin complet associé à 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 qui vient d’être jointe et en choisissant Renommer. J’ai renommé ma base de données en DataTutorials .

Renommez la base de données jointe en nom plus Human-Friendly

Figure 3 : Renommer la base de données jointe en nom plus Human-Friendly

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

Maintenant que nous avons attaché la NORTHWND.MDF base de données à partir du App_Data dossier, nous sommes prêts à ajouter l’infrastructure d’interrogation. 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 Visual Studio rouvert, explorez la base de données via l’Explorer server. Notez la nouvelle table (AspNet_SqlCacheTablesForChangeNotification), les nouvelles procédures stockées et les déclencheurs sur les Productstables , Categorieset 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, les déclencheurs et les procédures stockées nécessaires dans la base de données, la dernière étape consiste à configurer le service d’interrogation Web.config en 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. Lorsque vous utilisez des dépendances de cache SQL, nous devons faire référence au nom de la base de données définie ici, ainsi qu’à la table sur laquelle les données mises en cache sont basées. Nous allons voir comment utiliser la SqlCacheDependency classe pour associer par programmation des dépendances de cache SQL à des données mises en cache à 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 aspnet_regsql.exe en ligne de commande, retourne les tableName valeurs et changeId pour 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 élevée pollTime réduit le nombre de demandes de base de données, mais augmente le délai entre le moment où les données back-end changent et le moment où 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 ne retourne que quelques lignes à partir d’une table simple et légère. Mais n’essayez pas d’utiliser 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.

Notes

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 que vous souhaitez personnaliser la fréquence d’interrogation par base de données.

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

Aux étapes 1 à 4, nous avons examiné comment configurer l’infrastructure de base de données nécessaire et configurer le système d’interrogation. Une fois cette infrastructure en place, nous pouvons désormais 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 tutoriel Mise en cache des données avec ObjectDataSource a exploré les fonctionnalités de mise en cache déclarative 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 à partir de 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 déclarative des dépendances du cache SQL, ouvrez la SqlCacheDependencies.aspx page dans le Caching dossier et faites glisser un GridView à partir de la boîte à outils vers le Designer. Définissez gridView sur IDProductsDeclarative et, à partir de sa balise active, choisissez de le lier à un nouvel ObjetDataSource nommé ProductsDataSourceDeclarative.

Créer un objetDataSource nommé ProductsDataSourceDeclarative

Figure 5 : Créer un objetDataSource nommé ProductsDataSourceDeclarative (cliquer pour afficher l’image en taille réelle)

Configurez ObjectDataSource pour utiliser la ProductsBLL classe et définissez la liste déroulante de l’onglet SELECT sur GetProducts(). Sous 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.

Utiliser la surcharge UpdateProduct avec trois paramètres d’entrée

Figure 6 : Utiliser la surcharge UpdateProduct avec trois paramètres d’entrée (cliquer 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éfinissez la liste des Drop-Down sur (Aucun) pour les onglets INSERT et DELETE (Cliquer pour afficher l’image en taille réelle)

Après avoir terminé l’Assistant Configurer la source de données, Visual Studio crée BoundFields et CheckBoxFields dans gridView pour chacun des champs de données. Supprimez tous les champs sauf ProductName, CategoryNameet , et UnitPrice, et mettez ces champs en forme comme vous le souhaitez. À partir de la balise active de GridView, case activée les cases Activer la pagination, Activer le tri et Activer la modification. Visual Studio définit la propriété ObjectDataSource OldValuesParameterFormatString sur original_{0}. Pour que la fonctionnalité d’édition de GridView fonctionne correctement, supprimez cette propriété entièrement de la syntaxe déclarative ou définissez-la à sa valeur par défaut, {0}.

Enfin, ajoutez un contrôle Label Web au-dessus de GridView et définissez sa ID propriété sur ODSEvents et sa EnableViewState propriété sur false. Après avoir apporté ces modifications, le balisage déclaratif de votre page doit ressembler à ce qui suit. Notez que j’ai effectué un certain nombre de personnalisations esthétiques des 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 Selecting ObjectDataSource et ajoutez le code suivant :

protected void ProductsDataSourceDeclarative_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    ODSEvents.Text = "-- Selecting event fired";
}

Rappelez-vous que l’événement ObjectDataSource se Selecting déclenche uniquement lors de la récupération de 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é.

Maintenant, 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 le montre la figure 8.

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

Figure 8 : L’événement ObjectDataSource se Selecting déclenche chaque fois que le GridView est paginé, modifié ou trié (cliquez pour afficher l’image en taille réelle)

Comme nous l’avons vu dans le didacticiel Mise en cache des données avec ObjectDataSource , la définition de la EnableCaching propriété sur true entraîne la mise en cache de ses données par ObjectDataSource pendant la durée spécifiée par sa CacheDuration propriété. 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 comme 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 des données indéfiniment en fonction d’une dépendance de cache SQL par rapport à la table s Northwind Products , définissez la propriété ObjectDataSource EnableCaching sur true et sa SqlCacheDependency propriété sur NorthwindDB :Products .

Notes

Vous pouvez utiliser une dépendance de cache SQL et une expiration basée sur le temps en définissant EnableCachingtruesur , CacheDuration sur l’intervalle de temps et SqlCacheDependency sur les noms de base de données et de table. 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 product s 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 de dépendances de cache SQL sur des produits et des catégories

Figure 9 : Configurer ObjectDataSource pour prendre en charge la mise en cache à l’aide de dépendances du 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, revenez à la page via un navigateur. Là encore, le texte « Sélection de l’événement déclenché » doit apparaître lors de 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. En effet, une fois les données chargées dans le cache d’ObjectDataSource, elles y restent jusqu’à ce que les Products tables ou Categories soient modifiées ou que les données soient mises à jour via GridView.

Après avoir paginé dans la grille et avoir pris connaissance de l’absence du texte « Sélection de l’événement déclenché, ouvrez une nouvelle fenêtre de navigateur et accédez au tutoriel De base dans la section Modification, insertion et suppression (~/EditInsertDelete/Basics.aspx). Mettre à jour le nom ou le prix d’un produit. Ensuite, de à la première fenêtre de 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 de sélection déclenché doit réapparaître, car les données de base de données sous-jacentes ont été modifiées (voir 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. Il existe donc un délai entre la mise à jour des données sous-jacentes et la suppression des données mises en cache.

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

Figure 10 : La modification de la table Products supprime les données de produit mises en cache (cliquez pour afficher l’image en taille réelle)

Étape 6 : Utilisation programmatique de laSqlCacheDependencyclasse

Le tutoriel 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 à un couplage étroit de la mise en cache avec ObjectDataSource. Dans ce tutoriel, nous avons créé une ProductsCL classe pour illustrer l’utilisation programmatique 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 base de données et une paire de tables particulière. Le code suivant, par exemple, crée un SqlCacheDependency objet basé sur la table s de la base de Products données Northwind :

Caching.SqlCacheDependency productsTableDependency = 
    new Caching.SqlCacheDependency("NorthwindDB", "Products");

Les deux paramètres d’entrée du SqlCacheDependency constructeur s sont respectivement les noms de base de données et de table. Comme avec la propriété s SqlCacheDependency ObjectDataSource, le nom de 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 Insert des surcharges de méthode qui accepte une dépendance. Le code suivant ajoute de la valeur au cache de données pour une durée indéfinie, mais l’associe à un SqlCacheDependency sur la Products table. 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.

Caching.SqlCacheDependency productsTableDependency = 
    new Caching.SqlCacheDependency("NorthwindDB", "Products");
Cache.Insert(key, 
             value, 
             productsTableDependency, 
             System.Web.Caching.Cache.NoAbsoluteExpiration, 
             System.Web.Caching.Cache.NoSlidingExpiration);

La classe s de la couche de ProductsCL mise en cache met actuellement en cache les données de la table à l’aide Products d’une expiration basée sur le temps de 60 secondes. Mettons à jour cette classe afin qu’elle utilise plutôt des dépendances de cache SQL. 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 void AddCacheItem(string rawKey, object value)
{
    System.Web.Caching.Cache DataCache = HttpRuntime.Cache;
    // Make sure MasterCacheKeyArray[0] is in the cache
    DataCache[MasterCacheKeyArray[0]] = DateTime.Now;
    // Add a CacheDependency
    Caching.CacheDependency dependency =
        new Caching.CacheDependency(null, MasterCacheKeyArray);
    DataCache.Insert(GetCacheKey(rawKey), value, dependency, 
        DateTime.Now.AddSeconds(CacheDuration), 
        System.Web.Caching.Cache.NoSlidingExpiration);
}

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

private void AddCacheItem(string rawKey, object value)
{
    System.Web.Caching.Cache DataCache = HttpRuntime.Cache;
    // Add the SqlCacheDependency objects for Products
    Caching.SqlCacheDependency productsTableDependency = 
        new Caching.SqlCacheDependency("NorthwindDB", "Products");
    // Add the item to the data cache using productsTableDependency
    DataCache.Insert(GetCacheKey(rawKey), value, productsTableDependency, 
        Caching.Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration);
}

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

Configurer ObjectDataSource pour utiliser la classe ProductsCL

Figure 11 : Configurer ObjectDataSource pour utiliser la ProductsCL classe (cliquer pour afficher l’image en taille réelle)

Sélectionnez la méthode GetProducts dans la liste des Drop-Down onglets SELECT

Figure 12 : Sélectionnez la GetProducts méthode dans la liste des Drop-Down onglets SELECT (cliquez pour afficher l’image en taille réelle)

Choisissez la méthode UpdateProduct dans la liste des Drop-Down onglets UPDATE

Figure 13 : Choisissez la méthode UpdateProduct dans la liste des Drop-Down onglets UPDATE (cliquez pour afficher l’image en taille réelle)

Après avoir terminé l’Assistant Configurer la source de données, Visual Studio crée BoundFields et CheckBoxFields dans gridView pour chacun des champs de données. Comme avec le premier GridView ajouté à cette page, supprimez tous les champs sauf ProductName, CategoryNameet , et UnitPrice, et mettez ces champs en forme comme vous le souhaitez. À partir de la balise active de GridView, case activée les cases Activer la pagination, Activer le tri et Activer la modification. Comme avec ProductsDataSourceDeclarative ObjectDataSource, Visual Studio définit la ProductsDataSourceProgrammatic propriété ObjectDataSource OldValuesParameterFormatString sur original_{0}. Pour que la fonctionnalité d’édition de GridView fonctionne correctement, définissez cette propriété sur {0} (ou supprimez 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 du cache SQL dans la couche de mise en cache, définissez un point d’arrêt dans la méthode de classe ProductCL s AddCacheItem , puis démarrez 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 oblige GridView à réapprecher ses données, mais les données doivent être trouvées dans le cache, car la Products table de base de données n’a pas été modifiée. Si les données sont à plusieurs reprises introuvables dans le cache, vérifiez 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 tutoriel De base dans la section Modification, insertion et suppression (~/EditInsertDelete/Basics.aspx). Mettez à jour un enregistrement à partir de la table Products, puis, à partir de 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, ce qui indique 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 que SqlCacheDependencies.aspx les données sont désormais obsolètes. Si le point d’arrêt n’est pas atteint, c’est probablement parce que le service d’interrogation n’a pas encore déclenché depuis 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. Il existe donc un délai entre la mise à jour des données sous-jacentes et la suppression des données mises en cache.

Notes

Ce délai est plus susceptible d’apparaître lors de la modification d’un des produits via GridView dans SqlCacheDependencies.aspx. Dans le didacticiel Mise en cache des données dans l’architecture , nous avons ajouté la MasterCacheKeyArray dépendance de cache pour garantir que les données modifiées par le biais de la ProductsCL méthode class s UpdateProduct ont été supprimé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. Par conséquent, la ProductsCL classe continuera d’afficher les données mises en cache jusqu’à ce que le système d’interrogation note la modification apportée à la Products table. Nous verrons 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 méthode met en GetProductsByCategoryID(categoryID) cache les ProductsDataTables instances pour chaque valeur categoryID unique. Si l’un de ces objets est supprimé, la dépendance du MasterCacheKeyArray cache garantit que les autres sont également supprimés. Sans cette dépendance de cache, lorsque les données mises en cache sont modifiées, il est possible que d’autres données de produit mises en cache soient obsolètes. Par conséquent, il est important que nous maintenions la dépendance de cache lors de l’utilisation MasterCacheKeyArray de dépendances de cache SQL. Toutefois, la méthode s du cache de données n’autorise Insert qu’un seul objet de dépendance.

En outre, lorsque vous travaillez avec 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 mis en 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 que les données de produit mises en cache dépendent non seulement de la Products table, mais également des Categories tables et Suppliers .

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

Voici le code mis à jour pour la ProductsCL méthode de classe s AddCacheItem . La méthode crée la dépendance de MasterCacheKeyArray cache avec SqlCacheDependency des objets pour les Productstables , Categorieset Suppliers . Tous ces éléments sont combinés en un seul AggregateCacheDependency objet nommé aggregateDependencies, qui est ensuite passé dans la Insert méthode .

private void AddCacheItem(string rawKey, object value)
{
    System.Web.Caching.Cache DataCache = HttpRuntime.Cache;
    // Make sure MasterCacheKeyArray[0] is in the cache and create a depedency
    DataCache[MasterCacheKeyArray[0]] = DateTime.Now;
    Caching.CacheDependency masterCacheKeyDependency = 
        new Caching.CacheDependency(null, MasterCacheKeyArray);
    // Add the SqlCacheDependency objects for Products, Categories, and Suppliers
    Caching.SqlCacheDependency productsTableDependency = 
        new Caching.SqlCacheDependency("NorthwindDB", "Products");
    Caching.SqlCacheDependency categoriesTableDependency = 
        new Caching.SqlCacheDependency("NorthwindDB", "Categories");
    Caching.SqlCacheDependency suppliersTableDependency = 
        new Caching.SqlCacheDependency("NorthwindDB", "Suppliers");
    // Create an AggregateCacheDependency
    Caching.AggregateCacheDependency aggregateDependencies = 
        new Caching.AggregateCacheDependency();
    aggregateDependencies.Add(masterCacheKeyDependency, productsTableDependency, 
        categoriesTableDependency, suppliersTableDependency);
    DataCache.Insert(GetCacheKey(rawKey), value, aggregateDependencies, 
        Caching.Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration);
}

Testez ce nouveau code. Les modifications apportées aux Productstables , Categoriesou Suppliers entraînent la suppression des données mises en cache. En outre, la méthode s UpdateProduct de classeProductsCL, appelée lors de la modification d’un produit via GridView, supprime la dépendance de MasterCacheKeyArray cache, ce qui entraîne l’éviction du mis en ProductsDataTable cache et la récupération des données lors de la demande suivante.

Notes

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 soient 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 en cas de modification d’un résultat de requête. 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 !

En savoir plus

Pour plus d’informations sur les sujets abordés dans ce tutoriel, reportez-vous aux 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 comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Heures. Il est accessible à l’adressemitchell@4GuysFromRolla.com . ou via son blog, qui peut être trouvé à l’adresse http://ScottOnWriting.NET.

Un merci spécial à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Les principaux réviseurs 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.