Använda SQL Cache-beroenden (VB)

av Scott Mitchell

Ladda ned PDF

Den enklaste cachelagringsstrategin är att tillåta att cachelagrade data upphör att gälla efter en angiven tidsperiod. Men den här enkla metoden innebär att cachelagrade data inte har någon koppling till den underliggande datakällan, vilket resulterar i inaktuella data som hålls för långa eller aktuella data som har upphört att gälla för tidigt. En bättre metod är att använda klassen SqlCacheDependency så att data förblir cachelagrade tills dess underliggande data har ändrats i SQL-databasen. Den här handledningen visar hur.

Inledning

De cachelagringstekniker som undersöktes i Caching Data med ObjectDataSource och Caching Data i Arkitekturen använde en tidsbaserad utgångstid för att ta bort data från cacheminnet efter en specificerad period. Den här metoden är det enklaste sättet att balansera prestandafördelarna med cachelagring mot inaktuella data. Genom att välja en tidsförfallotid på x sekunder tillåter en sidutvecklare att få prestandafördelarna med cachelagring i bara x sekunder, men kan vara lugn med att hennes data aldrig blir inaktuella längre än högst x sekunder. För statiska data kan x naturligtvis utökas till webbprogrammets livslängd, vilket undersöktes i självstudien Cachelagringsdata vid programstart .

Vid cachelagring av databasdata väljs ofta en tidsbaserad förfallotid för enkel användning men är ofta en otillräcklig lösning. Helst skulle databasdata förbli cachelagrade tills underliggande data har ändrats i databasen. endast då skulle cachen avlägsnas. Den här metoden maximerar prestandafördelarna med cachelagring och minimerar varaktigheten för inaktuella data. För att kunna dra nytta av dessa fördelar måste det dock finnas ett system som vet när underliggande databasdata har ändrats och avlägsnar motsvarande objekt från cacheminnet. Innan ASP.NET 2.0 ansvarade sidutvecklare för att implementera det här systemet.

ASP.NET 2.0 tillhandahåller en SqlCacheDependency klass och nödvändig infrastruktur för att avgöra när en ändring har inträffat i databasen så att motsvarande cachelagrade objekt kan avlägsnas. Det finns två metoder för att avgöra när underliggande data har ändrats: meddelande och avsökning. När vi har diskuterat skillnaderna mellan aviseringar och avsökningar skapar vi den infrastruktur som krävs för att stödja avsökning och utforskar sedan hur du använder SqlCacheDependency klassen i deklarativa och programmatiska scenarier.

Förstå aviseringar och avsökningar

Det finns två metoder som kan användas för att avgöra när data i en databas har ändrats: avisering och avsökning. Genom en avisering meddelar databasen automatiskt ASP.NET-körtid när resultatet av en viss fråga har ändrats sedan frågan senast kördes, och då avlägsnas de cachelagrade objekt som är associerade med frågan. Med avsökning behåller databasservern information om när vissa tabeller senast har uppdaterats. ASP.NET-körningen avsöker regelbundet databasen för att kontrollera vilka tabeller som har ändrats sedan de angavs i cacheminnet. De tabeller vars data har ändrats får sina associerade cacheobjekt borttagna.

Meddelandealternativet kräver mindre konfiguration än avsökning och är mer detaljerat eftersom det spårar ändringar på frågenivå i stället för på tabellnivå. Tyvärr är meddelanden endast tillgängliga i de fullständiga utgåvorna av Microsoft SQL Server 2005 (dvs. icke-Express-utgåvorna). Avsökningsalternativet kan dock användas för alla versioner av Microsoft SQL Server från 7.0 till 2005. Eftersom de här självstudierna använder Express-utgåvan av SQL Server 2005 fokuserar vi på att konfigurera och använda avsökningsalternativet. Mer information om sql Server 2005-meddelandefunktioner finns i avsnittet Ytterligare läsning i slutet av den här självstudien.

Med avsökning måste databasen konfigureras så att den innehåller en tabell med namnet AspNet_SqlCacheTablesForChangeNotification som har tre kolumner – tableName, notificationCreatedoch changeId. Den här tabellen innehåller en rad för varje tabell som har data som kan behöva användas i ett SQL-cacheberoende i webbprogrammet. Kolumnen tableName anger tabellens namn medan notificationCreated anger datum och tid då raden lades till i tabellen. Kolumnen changeId är av typen int och har ett initialt värde på 0. Dess värde ökas med varje ändring i tabellen.

Förutom tabellen AspNet_SqlCacheTablesForChangeNotification måste databasen även innehålla utlösare för var och en av tabellerna som kan visas i ett SQL-cacheberoende. Dessa utlösare körs när en rad infogas, uppdateras eller tas bort och ökar tabellens changeId värde i AspNet_SqlCacheTablesForChangeNotification.

ASP.NET runtime-miljön spårar den aktuella changeId för en tabell när data cachelagras med ett SqlCacheDependency objekt. Databasen kontrolleras regelbundet och alla SqlCacheDependency objekt vars changeId skiljer sig från värdet i databasen avlägsnas eftersom ett annat changeId värde anger att tabellen har ändrats sedan data cachelagrades.

Steg 1: Utforskaaspnet_regsql.exekommandoradsprogrammet

Med avsökningsmetoden måste databasen konfigureras för att innehålla infrastrukturen som beskrivs ovan: en fördefinierad tabell (AspNet_SqlCacheTablesForChangeNotification), en handfull lagrade procedurer och utlösare för var och en av tabellerna som kan användas i SQL-cacheberoenden i webbprogrammet. Dessa tabeller, lagrade procedurer och utlösare kan skapas via kommandoradsprogrammet aspnet_regsql.exe, som finns i $WINDOWS$\Microsoft.NET\Framework\version mappen. Om du vill skapa tabellen AspNet_SqlCacheTablesForChangeNotification och tillhörande lagrade procedurer kör du följande från kommandoraden:

/* 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

Anmärkning

Om du vill köra dessa kommandon måste den angivna databasinloggningen finnas i rollerna db_securityadmin och db_ddladmin .

Om du till exempel vill lägga till infrastrukturen för avsökning till en Microsoft SQL Server-databas med namnet pubs på en databasserver med namnet ScottsServer med Windows-autentisering navigerar du till rätt katalog och anger:

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

När infrastrukturen på databasnivå har lagts till måste vi lägga till utlösarna i de tabeller som ska användas i SQL-cacheberoenden. aspnet_regsql.exe Använd kommandoradsprogrammet igen, men ange tabellnamnet med växeln -t och i stället för att använda växeln -ed använder du -et, så här:

/* 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

Om du vill lägga till utlösarna i tabellerna authors och titles i databasen på pubsScottsServeranvänder du:

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

I den här självstudien lägger du till utlösarna i tabellerna Products, Categories och Suppliers. Vi ska titta på den specifika kommandoradssyntaxen i steg 3.

Steg 2: Referera till en Microsoft SQL Server 2005 Express Edition-databas iApp_Data

Kommandoradsprogrammet aspnet_regsql.exe kräver databasen och servernamnet för att kunna lägga till nödvändig avsökningsinfrastruktur. Men vad är databasen och servernamnet för en Microsoft SQL Server 2005 Express-databas som finns i App_Data mappen? I stället för att behöva ta reda på vad databas- och servernamnen är har jag upptäckt att den enklaste metoden är att koppla databasen till databasinstansen localhost\SQLExpress och byta namn på data med SQL Server Management Studio. Om du har en av de fullständiga versionerna av SQL Server 2005 installerad på datorn har du förmodligen redan SQL Server Management Studio installerat på datorn. Om du bara har Express-utgåvan kan du ladda ned den kostnadsfria Microsoft SQL Server Management Studio.

Börja med att stänga Visual Studio. Öppna sedan SQL Server Management Studio och välj att ansluta till localhost\SQLExpress servern med Windows-autentisering.

Koppla till localhost\SQLExpress Server

Bild 1: Koppla till localhost\SQLExpress servern

När du har anslutit till servern visar Management Studio servern och har undermappar för databaser, säkerhet och så vidare. Högerklicka på mappen Databaser och välj alternativet Bifoga. Då visas dialogrutan Bifoga databaser (se bild 2). Klicka på knappen Lägg till och välj databasmappen NORTHWND.MDF i webbappens App_Data mapp.

Koppla NORTHWND. MDF-databas från mappen App_Data

Bild 2: Koppla NORTHWND.MDF databasen från mappen App_Data (Klicka om du vill visa en bild i full storlek)

Då läggs databasen till i mappen Databaser. Databasnamnet kan vara den fullständiga sökvägen till databasfilen eller den fullständiga sökvägen som föregås av ett GUID. Om du vill undvika att behöva skriva in det här långa databasnamnet när du använder kommandoradsverktyget aspnet_regsql.exe byter du namn på databasen till ett mer människovänligt namn genom att högerklicka på databasen som precis är ansluten och välja Byt namn. Jag har bytt namn på databasen till DataTutorials .

Byt namn på den bifogade databasen till ett mer Human-Friendly namn

Bild 3: Byt namn på den kopplade databasen till ett mer Human-Friendly namn

Steg 3: Lägga till avsökningsinfrastrukturen i Northwind-databasen

Nu när vi har kopplat NORTHWND.MDF databasen från App_Data mappen är vi redo att lägga till avsökningsinfrastrukturen. Förutsatt att du har bytt namn på databasen till DataTutorials kör du följande fyra kommandon:

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

När du har kört de här fyra kommandona högerklickar du på databasnamnet i Management Studio, går till undermenyn Uppgifter och väljer Koppla från. Stäng sedan Management Studio och öppna Visual Studio igen.

När Visual Studio har öppnats igen går du till databasen via ServerUtforskaren. Observera den nya tabellen (AspNet_SqlCacheTablesForChangeNotification), de nya lagrade procedurerna och utlösarna i tabellerna Products, Categoriesoch Suppliers .

Databasen innehåller nu nödvändig avsökningsinfrastruktur

Bild 4: Databasen innehåller nu nödvändig avsökningsinfrastruktur

Steg 4: Konfigurera avsökningstjänsten

När du har skapat nödvändiga tabeller, utlösare och lagrade procedurer i databasen är det sista steget att konfigurera avsökningstjänsten, vilket görs genom Web.config att ange vilka databaser som ska användas och avsökningsfrekvensen i millisekunder. Följande markering avsöker Northwind-databasen en gång i sekunden.

<?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>

Värdet name i elementet <add> ( NorthwindDB ) associerar ett läsbart namn med en viss databas. När du arbetar med SQL Cache-beroenden måste vi referera till databasnamnet som definieras här samt tabellen som cachelagrade data baseras på. Vi får se hur du använder SqlCacheDependency klassen för att programmatiskt associera SQL Cache-beroenden med cachelagrade data i steg 6.

När ett SQL-cacheberoende har upprättats ansluter avsökningssystemet till de databaser som definieras i elementen <databases> varje pollTime millisekunder och kör den AspNet_SqlCachePollingStoredProcedure lagrade proceduren. Den här lagrade proceduren – som lades till i steg 3 med aspnet_regsql.exe-kommandoradsverktyget – returnerar de tableName-värdena och changeId-värdet för varje post i AspNet_SqlCacheTablesForChangeNotification. Inaktuella SQL Cache-beroenden avlägsnas från cachen.

Inställningen pollTime introducerar en kompromiss mellan prestanda och inaktuella data. Ett litet pollTime värde ökar antalet begäranden till databasen, men tar snabbare bort inaktuella data från cachen. Ett större pollTime värde minskar antalet databasbegäranden, men ökar fördröjningen mellan när serverdelsdata ändras och när relaterade cacheobjekt tas bort. Lyckligtvis kör databasbegäran en enkel lagrad procedur som returnerar bara några rader från en enkel, lätt tabell. Men experimentera med olika pollTime värden för att hitta en idealisk balans mellan databasåtkomst och inaktuella data för ditt program. Det minsta pollTime tillåtna värdet är 500.

Anmärkning

Exemplet ovan innehåller ett enda pollTime värde i elementet <sqlCacheDependency> , men du kan också ange pollTime värdet i elementet <add> . Det här är användbart om du har flera angivna databaser och vill anpassa avsökningsfrekvensen per databas.

Steg 5: Deklarativt arbete med SQL Cache-beroenden

I steg 1 till och med 4 tittade vi på hur du konfigurerar den nödvändiga databasinfrastrukturen och konfigurerar avsökningssystemet. Med den här infrastrukturen på plats kan vi nu lägga till objekt i datacachen med ett associerat SQL-cacheberoende med hjälp av antingen programmatiska eller deklarativa tekniker. I det här steget ska vi undersöka hur du deklarativt arbetar med SQL-cacheberoenden. I steg 6 tittar vi på den programmatiska metoden.

Självstudien Cachelagring av data med ObjectDataSource utforskade möjligheterna för deklarativ cachelagring med komponenten ObjectDataSource. Genom att helt enkelt ange EnableCaching egenskapen till True och CacheDuration egenskapen till ett tidsintervall cachelagrar ObjectDataSource automatiskt data som returneras från dess underliggande objekt för det angivna intervallet. ObjectDataSource kan också använda ett eller flera SQL-cacheberoenden.

Om du vill demonstrera användningen av SQL-cacheberoenden deklarativt öppnar SqlCacheDependencies.aspx du sidan i Caching mappen och drar en GridView från verktygslådan till designern. Ange GridView s ID till ProductsDeclarative och från dess smarta tagg väljer du att binda den till en ny ObjectDataSource med namnet ProductsDataSourceDeclarative.

Skapa en ny ObjectDataSource med namnet ProductsDataSourceDeclarative

Bild 5: Skapa en ny ObjectDataSource med namnet ProductsDataSourceDeclarative (Klicka om du vill visa en bild i full storlek)

Konfigurera ObjectDataSource att använda ProductsBLL klassen och ange listrutan på fliken SELECT till GetProducts(). På fliken UPPDATERA väljer du överlagringen UpdateProduct med tre indataparametrar – productName, unitPriceoch productID. Ställ in listrutorna på (Ingen) på flikarna "INSERT" och "DELETE".

Använda UpdateProduct Overload med tre indataparametrar

Bild 6: Använd UpdateProduct Overload med tre indataparametrar (Klicka om du vill visa en bild i full storlek)

Ange Drop-Down lista till (Ingen) för flikarna INSERT och DELETE

Bild 7: Ange Drop-Down lista till (Ingen) för flikarna INSERT och DELETE (Klicka om du vill visa en bild i full storlek)

När du har slutfört guiden Konfigurera datakälla skapar Visual Studio BoundFields och CheckBoxFields i GridView för vart och ett av datafälten. Ta bort alla fält men ProductName, CategoryNameoch UnitPriceoch formatera dessa fält som du vill. Markera kryssrutorna Aktivera sidindelning, Aktivera sortering och Aktivera redigering i GridView:s smarta tagg. Visual Studio anger egenskapen ObjectDataSource OldValuesParameterFormatString till original_{0}. För att Funktionen För redigering av GridView ska fungera korrekt tar du antingen bort den här egenskapen helt från den deklarativa syntaxen eller ställer tillbaka den till dess standardvärde, {0}.

Lägg slutligen till en etikettwebbkontroll ovanför GridView och ange dess ID egenskap till ODSEvents och dess EnableViewState egenskap till False. När du har gjort de här ändringarna bör sidans deklarativa markering se ut ungefär så här. Observera att jag har gjort ett antal estetiska anpassningar till GridView-fälten som inte är nödvändiga för att demonstrera SQL Cache-beroendefunktionen.

<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>

Skapa sedan en händelsehanterare för ObjectDataSource-händelsen Selecting och lägg sedan till följande kod:

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

Kom ihåg att ObjectDataSource-händelsen Selecting endast utlöses när data hämtas från dess underliggande objekt. Om ObjectDataSource kommer åt data från sin egen cache utlöses inte den här händelsen.

Gå nu till den här sidan via en webbläsare. Eftersom vi ännu inte har implementerat cachelagring bör sidan varje gång du navigerar mellan sidorna, sorterar eller redigerar rutnätet visa texten "Valhändelse initierad", som bild 8 visar.

ObjectDataSource valhändelsen utlöses varje gång GridView pagineras, redigeras eller sorteras

Bild 8: Händelsen ObjectDataSource utlöses Selecting varje gång GridView är sidsidigt, redigerat eller sorterat (klicka om du vill visa en bild i full storlek)

Som vi såg i handledningen Cachelagring av data med ObjectDataSource innebär att inställningen av EnableCaching-egenskapen för True gör att ObjectDataSource cachelagrar sina data under den tid som anges av dess CacheDuration-egenskap. ObjectDataSource har också en SqlCacheDependency egenskap som lägger till ett eller flera SQL Cache-beroenden till cachelagrade data med hjälp av mönstret:

databaseName1:tableName1;databaseName2:tableName2;...

Där databaseName är namnet på databasen enligt attributet för name elementet <add> i Web.config, och tableName är namnet på databastabellen. Om du till exempel vill skapa en ObjectDataSource som cachelagrar data på obestämd tid baserat på ett SQL-cacheberoende mot Northwind-tabellen Products ställer du in egenskapen EnableCaching ObjectDataSource på True och dess SqlCacheDependency egenskap till NorthwindDB:Products .

Anmärkning

Du kan använda ett SQL-cacheberoende och ett tidsbaserat förfallodatum genom att EnableCachingange True till , CacheDuration till tidsintervallet och SqlCacheDependency till databasen och tabellnamnen. ObjectDataSource tar bort sina data när den tidsbaserade förfallotiden nås eller när avsökningssystemet noterar att underliggande databasdata har ändrats, beroende på vilket som inträffar först.

GridView i SqlCacheDependencies.aspx visar data från två tabeller – Products och Categories (produktens CategoryName-fält hämtas via en JOINCategories). Därför vill vi ange två SQL-cacheberoenden: NorthwindDB:Products; NorthwindDB:Categories .

Konfigurera ObjectDataSource för att stödja cachelagring med SQL Cache-beroenden för produkter och kategorier

Bild 9: Konfigurera ObjectDataSource så att den stöder cachelagring med HJÄLP av SQL Cache-beroenden på Products och Categories (Klicka om du vill visa en bild i full storlek)

När du har konfigurerat ObjectDataSource som stöd för cachelagring går du tillbaka till sidan via en webbläsare. Återigen bör texten 'Händelse "Välj" utlöses' visas vid det första sidbesöket, men bör försvinna när man bläddrar, sorterar eller klickar på knapparna Redigera eller Avbryt. Det beror på att när data har lästs in i ObjectDataSources cache, finns de kvar tills Products eller Categories tabellerna har ändrats eller data uppdateras via GridView.

När du har bläddrat igenom rutnätet och observerat att texten för 'händelsen för val' saknas, öppna ett nytt webbläsarfönster och gå till grundläggande handledning i avsnittet Redigera, Infoga och Ta bort (~/EditInsertDelete/Basics.aspx). Uppdatera namnet eller priset på en produkt. Från till det första webbläsarfönstret visar du sedan en annan sida med data, sorterar rutnätet eller klickar på en rads redigera-knapp. Den här gången ska "Valhändelsen utlöses" visas igen, eftersom den underliggande databasen har ändrats (se bild 10). Om texten inte visas väntar du en stund och försöker igen. Kom ihåg att avsökningstjänsten söker efter ändringar i Products tabellen varje pollTime millisekunder, så det uppstår en fördröjning mellan när underliggande data uppdateras och när cachelagrade data tas bort.

Om du ändrar produkttabellen avlägsnas cachelagrade produktdata

Bild 10: Om du ändrar produkttabellen avlägsnas cachelagrade produktdata (Klicka om du vill visa en bild i full storlek)

Steg 6: Arbeta programmatiskt medSqlCacheDependencyklassen

Självstudien om cachelagring i arkitekturen undersökte fördelarna med att använda ett separat cachelager i arkitekturen, istället för att nära koppla cachelagringen till ObjectDataSource. I den självstudien skapade vi en ProductsCL klass för att demonstrera programmatiskt arbete med datacachen. Om du vill använda SQL Cache-beroenden i cachelagringsskiktet SqlCacheDependency använder du klassen .

Med avsökningssystemet måste ett SqlCacheDependency objekt associeras med en viss databas och ett visst tabellpar. Följande kod skapar till exempel ett SqlCacheDependency objekt baserat på Northwind-databasens Products tabell:

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

De två indataparametrarna till SqlCacheDependency konstruktorn är databas- respektive tabellnamnen. Precis som med egenskapen ObjectDataSource är SqlCacheDependency det databasnamn som används samma som värdet som anges i name -attributet för elementet <add> i Web.config. Tabellnamnet är det faktiska namnet på databastabellen.

Om du vill associera en SqlCacheDependency med ett objekt som lagts till i datacachen använder du någon av de Insert metodöverlagringar som accepterar ett beroende. Följande kod lägger till värde i datacachen på obestämd tid, men associerar den med en SqlCacheDependency i Products tabellen. Kort sagt kommer värdet att finnas kvar i cacheminnet tills det tas bort på grund av minnesbegränsningar eller på grund av att pollningssystemet har upptäckt att tabellen har ändrats sedan det lades i cacheminnet.

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

Klassen Cachelagringslager cachelagrar ProductsCL för närvarande data från Products tabellen med en tidsbaserad förfallotid på 60 sekunder. Låt oss uppdatera den här klassen så att den använder SQL-cacheberoenden i stället. Metoden ProductsCL class s AddCacheItem , som ansvarar för att lägga till data i cacheminnet, innehåller för närvarande följande kod:

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

Uppdatera den här koden för att använda ett SqlCacheDependency objekt i stället för MasterCacheKeyArray cacheberoendet:

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

Om du vill testa den här funktionen lägger du till en GridView på sidan under den befintliga ProductsDeclarative GridView. Ange den nya GridView ID till ProductsProgrammatic och, genom sin smarta tagg, binda den till en ny ObjectDataSource med namnet ProductsDataSourceProgrammatic. Konfigurera ObjectDataSource att använda ProductsCL klassen och ange listrutorna på flikarna SELECT respektive UPDATE till GetProducts respektive UpdateProduct.

Konfigurera ObjectDataSource att använda ProductsCL-klassen

Bild 11: Konfigurera ObjectDataSource att använda ProductsCL klassen (Klicka om du vill visa en bild i full storlek)

Välj metoden GetProducts i listan SELECT Tab s Drop-Down

Bild 12: Välj GetProducts metoden från SELECT Tab s Drop-Down List (Klicka om du vill visa en bild i full storlek)

Välj updateproduct-metoden på fliken UPDATE s Drop-Down list

Bild 13: Välj metoden UpdateProduct från fliken UPDATE Drop-Down (Klicka om du vill visa en bild i full storlek)

När du har slutfört guiden Konfigurera datakälla skapar Visual Studio BoundFields och CheckBoxFields i GridView för vart och ett av datafälten. Precis som med den första GridView som lagts till på den här sidan tar du bort alla fält men ProductName, CategoryNameoch och UnitPriceformaterar dessa fält som du vill. Markera kryssrutorna Aktivera sidindelning, Aktivera sortering och Aktivera redigering i GridView:s smarta tagg. Precis som med ProductsDataSourceDeclarative ObjectDataSource kommer Visual Studio att ange egenskapen ProductsDataSourceProgrammatic för ObjectDataSource till OldValuesParameterFormatString. För att Funktionen För redigering av GridView ska fungera korrekt anger du tillbaka den här egenskapen till {0} (eller tar bort egenskapstilldelningen från den deklarativa syntaxen helt och hållet).

När du har slutfört dessa uppgifter bör den resulterande deklarativa markeringen för GridView och ObjectDataSource se ut så här:

<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>

Om du vill testa SQL-cacheberoendet i cachelagringsskiktet anger du en brytpunkt i ProductCL klassens AddCacheItem -metod och börjar sedan felsöka. När du först besöker SqlCacheDependencies.aspx ska brytpunkten slås eftersom data begärs för första gången och placeras i cacheminnet. Gå sedan till en annan sida i GridView eller sortera en av kolumnerna. Detta gör att GridView behåller sina data, men data bör hittas i cacheminnet eftersom databastabellen Products inte har ändrats. Om data upprepade gånger inte hittas i cacheminnet kontrollerar du att det finns tillräckligt med minne på datorn och försök igen.

När du har bläddrat igenom några sidor i GridView öppnar du ett andra webbläsarfönster och navigerar till självstudiekursen Grundläggande i avsnittet Redigera, Infoga och Ta bort (~/EditInsertDelete/Basics.aspx). Uppdatera en post från tabellen Produkter och visa sedan en ny sida i det första webbläsarfönstret eller klicka på en av sorteringsrubrikerna.

I det här scenariot visas en av två saker: antingen slås brytpunkten, vilket anger att cachelagrade data har avlägsnats på grund av ändringen i databasen. eller så kommer brytpunkten inte att slås, vilket innebär att SqlCacheDependencies.aspx nu visar inaktuella data. Om brytpunkten inte nås beror det troligtvis på att pollingtjänsten ännu inte har utlösts sedan data uppdaterades. Kom ihåg att avsökningstjänsten söker efter ändringar i Products tabellen varje pollTime millisekunder, så det uppstår en fördröjning mellan när underliggande data uppdateras och när cachelagrade data tas bort.

Anmärkning

Det är mer troligt att den här fördröjningen visas när du redigerar en av produkterna via GridView i SqlCacheDependencies.aspx. I självstudien Cachelagring av data i arkitekturen lade vi till cacheberoendet för att säkerställa att data som redigeras genom klassens MasterCacheKeyArray metod ProductsCL togs bort från cachen. Vi ersatte dock det här cacheberoendet när vi ändrade AddCacheItem metoden tidigare i det här steget och därför ProductsCL fortsätter klassen att visa cachelagrade data tills avsökningssystemet noterar ändringen i Products tabellen. Vi får se hur du återinför MasterCacheKeyArray cacheberoendet i steg 7.

Steg 7: Associera flera beroenden med ett cachelagrat objekt

Kom ihåg att MasterCacheKeyArray cacheberoendet används för att säkerställa att alla produktrelaterade data tas bort från cacheminnet när ett enskilt objekt som är associerat i det uppdateras. Till exempel cachelagrar GetProductsByCategoryID(categoryID)-metoden ProductsDataTables-instanser för varje unikt categoryID-värde. Om ett av dessa objekt tas bort ser cacheberoendet MasterCacheKeyArray till att de andra också tas bort. Utan det här cacheberoendet finns det en risk att andra cachelagrade produktdata är inaktuella när cachelagrade data ändras. Därför är det viktigt att vi upprätthåller MasterCacheKeyArray cacheberoendet när du använder SQL-cacheberoenden. Datacachens-metoden Insert tillåter dock endast ett enda beroendeobjekt.

När vi arbetar med SQL Cache-beroenden kan vi dessutom behöva associera flera databastabeller som beroenden. Till exempel innehåller den ProductsDataTable cachelagrade i ProductsCL klassen kategorin och leverantörsnamnen för varje produkt, men AddCacheItem metoden använder bara ett beroende av Products. I det här fallet, om användaren uppdaterar namnet på en kategori eller leverantör, kommer cachelagrade produktdata att finnas kvar i cacheminnet och vara inaktuella. Därför vill vi göra cachelagrade produktdata beroende av inte bara Products tabellen, utan även tabellerna Categories och Suppliers .

KlassenAggregateCacheDependency ger ett sätt att associera flera beroenden med ett cacheobjekt. Börja med att skapa en AggregateCacheDependency instans. Lägg sedan till uppsättningen med beroenden med hjälp av AggregateCacheDependency s-metoden Add . När du därefter infogar objektet i datacachen, skickar du in AggregateCacheDependency-instansen. När något av AggregateCacheDependency instansens beroenden ändras tas det cachelagrade objektet bort.

Följande visar den uppdaterade koden för ProductsCL metoden class s AddCacheItem . Metoden skapar MasterCacheKeyArray cacheberoendet tillsammans med SqlCacheDependency objekt för tabellerna Products, Categoriesoch Suppliers . Alla dessa kombineras till ett AggregateCacheDependency objekt med namnet aggregateDependencies, som sedan skickas till Insert metoden.

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

Testa den nya koden. Nu gör ändringar i tabellerna Products, Categorieseller Suppliers att cachelagrade data tas bort. Dessutom avlägsnar klassens ProductsCL metod UpdateProduct, som anropas vid redigering av en produkt via GridView, cacheberoendet MasterCacheKeyArray, vilket gör att det cachelagrade ProductsDataTable tas bort och data hämtas på nytt vid nästa begäran.

Anmärkning

SQL-cacheberoenden kan också användas med cachelagring av utdata. En demonstration av den här funktionen finns i: Använda ASP.NET cachelagring av utdata med SQL Server.

Sammanfattning

Vid cachelagring av databasdata finns data helst kvar i cacheminnet tills de ändras i databasen. Med ASP.NET 2.0 kan SQL-cacheberoenden skapas och användas i både deklarativa och programmatiska scenarier. En av utmaningarna med den här metoden är att upptäcka när data har ändrats. De fullständiga versionerna av Microsoft SQL Server 2005 innehåller meddelandefunktioner som kan avisera ett program när ett frågeresultat har ändrats. För Express Edition av SQL Server 2005 och äldre versioner av SQL Server måste ett avsökningssystem användas i stället. Lyckligtvis är det ganska enkelt att konfigurera den nödvändiga avsökningsinfrastrukturen.

Lycka till med programmerandet!

Ytterligare läsning

Mer information om de ämnen som beskrivs i den här självstudien finns i följande resurser:

Om författaren

Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.

Särskilt tack till

Den här självstudieserien granskades av många användbara granskare. Huvudgranskare för den här handledningen var Marko Rangel, Teresa Murphy och Hilton Giesenow. Vill du granska mina kommande MSDN-artiklar? Om så är fallet, hör av dig på mitchell@4GuysFromRolla.com.