Sdílet prostřednictvím


Použití závislostí mezipaměti SQL (C#)

Scott Mitchell

Stáhnout PDF

Nejjednodušší strategií ukládání do mezipaměti je umožnit vypršení platnosti dat uložených v mezipaměti po zadaném časovém období. Tento jednoduchý přístup ale znamená, že data uložená v mezipaměti si neudržují žádnou spojitost se svým podkladovým zdrojem dat, což vede k příliš dlouhým zastaralým datům nebo k vypršení jejich platnosti příliš brzy. Lepším přístupem je použití třídy SqlCacheDependency, aby data zůstala uložená v mezipaměti, dokud se jejich podkladová data nezmění v databázi SQL. V tomto kurzu se dozvíte, jak na to.

Úvod

Techniky ukládání do mezipaměti, které se zkoumaly v části Ukládání dat do mezipaměti s objectDataSource a Ukládání dat do mezipaměti v kurzech Architektury, používaly vypršení platnosti na základě času k vyřazení dat z mezipaměti po zadané době. Tento přístup představuje nejjednodušší způsob, jak vyvážit zvýšení výkonu při ukládání do mezipaměti a neaktuálnost dat. Výběrem časového limitu x sekund vývojář stránky připouští, že může využívat výhody výkonu ukládání do mezipaměti pouze x sekund, ale může si odpočinout, že data nikdy nebudou zastaralá déle než maximálně x sekund. U statických dat je samozřejmě možné x prodloužit na dobu životnosti webové aplikace, jak jsme si prohlédli v kurzu Ukládání dat do mezipaměti při spuštění aplikace .

Při ukládání dat databáze do mezipaměti se často volí vypršení platnosti na základě času z důvodu snadného použití, ale často se jedná o nedostatečné řešení. V ideálním případě by data databáze zůstala uložena v mezipaměti, dokud nebudou podkladová data v databázi změněna; pak by se mezipaměť vyřadila. Tento přístup maximalizuje výkonové výhody ukládání do mezipaměti a minimalizuje dobu trvání zastaralých dat. Aby však bylo možné tyto výhody využívat, musí existovat systém, který ví, kdy byla podkladová data databáze upravena, a vyřadí odpovídající položky z mezipaměti. Před ASP.NET 2.0 byli vývojáři stránek zodpovědní za implementaci tohoto systému.

ASP.NET 2.0 poskytuje SqlCacheDependency třídu a potřebnou infrastrukturu pro určení, kdy došlo ke změně v databázi, aby bylo možné vyřadit odpovídající položky uložené v mezipaměti. Existují dvě techniky, jak určit, kdy se podkladová data změnila: oznámení a dotazování. Po probrání rozdílů mezi oznámením a dotazováním vytvoříme infrastrukturu potřebnou k podpoře dotazování a pak prozkoumáme, jak třídu používat SqlCacheDependency v deklarativních a programových scénářích.

Principy oznámení a dotazování

Existují dvě techniky, které lze použít k určení, kdy byla data v databázi změněna: oznámení a dotazování. S oznámením databáze automaticky upozorní modul runtime ASP.NET, když se od posledního spuštění dotazu změnily výsledky konkrétního dotazu a v tomto okamžiku se položky v mezipaměti přidružené k dotazu vyřadí. Při dotazování databázový server udržuje informace o tom, kdy byly konkrétní tabulky naposledy aktualizovány. Modul runtime ASP.NET se pravidelně dotazuje databáze, aby zkontroloval, jaké tabulky se změnily od jejich zadání do mezipaměti. U tabulek, jejichž data byla změněna, se vyřadí přidružené položky mezipaměti.

Možnost oznámení vyžaduje méně nastavení než dotazování a je podrobnější, protože sleduje změny na úrovni dotazu, nikoli na úrovni tabulky. Oznámení jsou bohužel k dispozici pouze v úplných edicích Microsoft SQL Server 2005 (tj. edicích, které nejsou Express). Možnost dotazování se ale dá použít pro všechny verze Microsoft SQL Server od 7.0 do 2005. Vzhledem k tomu, že tyto kurzy používají edici Express SQL Server 2005, zaměříme se na nastavení a použití možnosti dotazování. Další zdroje informací o možnostech oznámení SQL Server 2005 najdete v části Další materiály na konci tohoto kurzu.

Při dotazování musí být databáze nakonfigurovaná tak, aby obsahovala tabulku s názvem AspNet_SqlCacheTablesForChangeNotification , která má tři sloupce – tableName, notificationCreateda changeId. Tato tabulka obsahuje řádek pro každou tabulku obsahující data, která může být potřeba použít v závislosti mezipaměti SQL ve webové aplikaci. Sloupec tableName určuje název tabulky a zároveň notificationCreated označuje datum a čas, kdy byl řádek přidán do tabulky. Sloupec changeId je typu int a má počáteční hodnotu 0. Jeho hodnota se s každou úpravou tabulky navyšuje.

Kromě AspNet_SqlCacheTablesForChangeNotification tabulky musí databáze také obsahovat aktivační události pro každou z tabulek, které se můžou objevit v závislosti mezipaměti SQL. Tyto triggery se spustí při každém vložení, aktualizaci nebo odstranění řádku a zvýšení hodnoty tabulky changeId v AspNet_SqlCacheTablesForChangeNotification.

Modul runtime ASP.NET sleduje aktuální stav changeId tabulky při ukládání dat do mezipaměti pomocí objektu SqlCacheDependency . Databáze je pravidelně kontrolována a všechny SqlCacheDependency objekty, jejichž changeId se liší od hodnoty v databázi, jsou vyřazeny, protože odlišná changeId hodnota značí, že od uložení dat do mezipaměti došlo ke změně tabulky.

Krok 1: Prozkoumání programu příkazovéhoaspnet_regsql.exeřádku

U přístupu s dotazováním musí být databáze nastavená tak, aby obsahovala infrastrukturu popsanou výše: předdefinovanou tabulku (AspNet_SqlCacheTablesForChangeNotification), několik uložených procedur a triggery pro každou z tabulek, které se dají použít v závislostech mezipaměti SQL ve webové aplikaci. Tyto tabulky, uložené procedury a triggery lze vytvořit prostřednictvím programu aspnet_regsql.exepříkazového řádku , který se nachází ve $WINDOWS$\Microsoft.NET\Framework\version složce . Pokud chcete vytvořit AspNet_SqlCacheTablesForChangeNotification tabulku a přidružené uložené procedury, spusťte z příkazového řádku následující příkaz:

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

Poznámka

Aby bylo možné tyto příkazy spustit, musí být zadané přihlášení k databázi v rolích db_securityadmin a db_ddladmin .

Pokud například chcete přidat infrastrukturu pro dotazování do databáze Microsoft SQL Server s názvem pubs na databázovém serveru s názvem ScottsServer pomocí ověřování systému Windows, přejděte do příslušného adresáře a z příkazového řádku zadejte:

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

Po přidání infrastruktury na úrovni databáze musíme do těchto tabulek přidat triggery, které se budou používat v závislostech mezipaměti SQL. Znovu použijte program příkazového aspnet_regsql.exe řádku, ale zadejte název tabulky pomocí -t přepínače a místo -ed přepínače použijte -et, například takto:

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

Pokud chcete přidat triggery do authors tabulek a titles v databázi na pubsScottsServer, použijte:

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

Pro účely tohoto kurzu přidejte triggery do Productstabulek , Categoriesa Suppliers . Na konkrétní syntaxi příkazového řádku se podíváme v kroku 3.

Krok 2: Odkazování na databázi Microsoft SQL Server 2005 Express Edition vApp_Data

Program aspnet_regsql.exe příkazového řádku vyžaduje název databáze a serveru, aby mohl přidat potřebnou infrastrukturu dotazování. Jaký je ale název databáze a serveru pro databázi Microsoft SQL Server 2005 Express, která se nachází ve App_Data složce? Místo toho, abyste museli zjišťovat názvy databází a serverů, zjistil jsem, že nejjednodušším přístupem je připojit databázi k localhost\SQLExpress instanci databáze a přejmenovat data pomocí SQL Server Management Studio. Pokud máte na počítači nainstalovanou jednu z úplných verzí SQL Server 2005, pravděpodobně už máte v počítači nainstalovanou SQL Server Management Studio. Pokud máte jenom edici Express, můžete si stáhnout bezplatnou verzi Microsoft SQL Server Management Studio Express Edition.

Začněte zavřením sady Visual Studio. Pak otevřete SQL Server Management Studio a zvolte připojení k localhost\SQLExpress serveru pomocí ověřování systému Windows.

Připojení k serveru localhost\SQLExpress Server

Obrázek 1: Připojení k localhost\SQLExpress serveru

Po připojení k serveru management Studio zobrazí server a podsložky pro databáze, zabezpečení atd. Klikněte pravým tlačítkem na složku Databáze a zvolte možnost Připojit. Zobrazí se dialogové okno Připojit databáze (viz obrázek 2). Klikněte na tlačítko Přidat a vyberte NORTHWND.MDF složku databáze ve složce s vaší webové aplikace App_Data .

Připojte sadu NORTHWND. Databáze MDF ze složky App_Data

Obrázek 2: Připojení NORTHWND.MDF databáze ze App_Data složky (kliknutím zobrazíte obrázek v plné velikosti)

Tím se databáze přidá do složky Databáze. Název databáze může být úplná cesta k souboru databáze nebo úplná cesta s identifikátorem GUID. Abyste nemuseli při použití nástroje aspnet_regsql.exe příkazového řádku zadávat tento dlouhý název databáze, přejmenujte databázi na uživatelsky přívětivější název tak, že kliknete pravým tlačítkem na právě připojenou databázi a zvolíte Přejmenovat. Přejmenoval(a) jsem svou databázi na DataTutorials .

Přejmenování připojené databáze na název s více Human-Friendly

Obrázek 3: Přejmenování připojené databáze na další Human-Friendly název

Krok 3: Přidání infrastruktury dotazování do databáze Northwind

Teď, když jsme připojili NORTHWND.MDF databázi ze App_Data složky, jsme připraveni přidat infrastrukturu dotazování. Za předpokladu, že jste databázi přejmenovali na DataTutorials, spusťte následující čtyři příkazy:

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

Po spuštění těchto čtyř příkazů klikněte pravým tlačítkem na název databáze v management studiu, přejděte do podnabídky Úlohy a zvolte Odpojit. Pak zavřete Management Studio a znovu otevřete Sadu Visual Studio.

Po opětovném otevření sady Visual Studio přejděte k podrobnostem databáze prostřednictvím Průzkumníka serveru. Všimněte si nové tabulky (AspNet_SqlCacheTablesForChangeNotification), nových uložených procedur a triggerů v Productstabulkách , Categoriesa Suppliers .

Databáze teď obsahuje potřebnou infrastrukturu dotazování.

Obrázek 4: Databáze teď zahrnuje potřebnou infrastrukturu dotazování

Krok 4: Konfigurace služby dotazování

Po vytvoření potřebných tabulek, triggerů a uložených procedur v databázi je posledním krokem konfigurace služby dotazování, kterou provedete Web.config zadáním databází, které se mají použít, a frekvence dotazování v milisekundách. Následující kód dotazuje databázi Northwind jednou za sekundu.

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

Hodnota name v elementu <add> ( NorthwindDB ) přidruží název čitelný pro člověka ke konkrétní databázi. Při práci se závislostmi mezipaměti SQL budeme muset odkazovat na zde definovaný název databáze a také na tabulku, na které jsou založená data uložená v mezipaměti. V kroku 6 uvidíme, jak pomocí SqlCacheDependency třídy programově přidružit závislosti mezipaměti SQL k datům uloženým v mezipaměti.

Po vytvoření závislosti mezipaměti SQL se systém dotazování připojí k databázím definovaným v <databases> prvcích každých pollTime milisekund a spustí uloženou proceduru AspNet_SqlCachePollingStoredProcedure . Tato uložená procedura, která byla přidána zpět v kroku 3 pomocí nástroje příkazového aspnet_regsql.exe řádku , vrátí tableName hodnoty a changeId pro každý záznam v AspNet_SqlCacheTablesForChangeNotificationsouboru . Zastaralé závislosti mezipaměti SQL se z mezipaměti vyřadí.

Nastavení pollTime zavádí kompromis mezi výkonem a zastaralostí dat. Malá pollTime hodnota zvýší počet požadavků na databázi, ale rychleji vyřadí zastaralá data z mezipaměti. Větší pollTime hodnota snižuje počet databázových požadavků, ale zvyšuje zpoždění mezi změnami dat back-endu a vyřazením souvisejících položek mezipaměti. Databázový požadavek naštěstí spouští jednoduchou uloženou proceduru, která vrací jen několik řádků z jednoduché, zjednodušené tabulky. Experimentujte ale s různými pollTime hodnotami, abyste našli ideální rovnováhu mezi přístupem k databázi a zastaralostí dat pro vaši aplikaci. Nejmenší pollTime povolená hodnota je 500.

Poznámka

Výše uvedený příklad poskytuje jednu pollTime hodnotu v elementu <sqlCacheDependency> , ale volitelně můžete zadat pollTime hodnotu v elementu <add> . To je užitečné, pokud máte zadaných více databází a chcete přizpůsobit frekvenci dotazování na databázi.

Krok 5: Deklarativní práce se závislostmi mezipaměti SQL

V krocích 1 až 4 jsme se podívali na to, jak nastavit potřebnou infrastrukturu databáze a nakonfigurovat systém dotazování. Díky této infrastruktuře teď můžeme přidávat položky do mezipaměti dat s přidruženou závislostí mezipaměti SQL pomocí programových nebo deklarativních technik. V tomto kroku prozkoumáme, jak deklarativně pracovat se závislostmi mezipaměti SQL. V kroku 6 se podíváme na programový přístup.

Kurz Ukládání dat do mezipaměti pomocí ObjectDataSource prozkoumal možnosti deklarativního ukládání do mezipaměti objectDataSource. Když jednoduše nastavíte EnableCaching vlastnost na true a CacheDuration vlastnost na určitý časový interval, ObjectDataSource automaticky uloží data vrácená ze svého podkladového objektu do mezipaměti po zadaný interval. ObjectDataSource může také použít jednu nebo více závislostí mezipaměti SQL.

Chcete-li demonstrovat použití závislostí mezipaměti SQL deklarativně, otevřete SqlCacheDependencies.aspx stránku ve Caching složce a přetáhněte Objekt GridView z panelu nástrojů na Designer. Nastavte Objekt GridView ID na ProductsDeclarative a z jeho inteligentní značky zvolte, že se má vytvořit vazba na nový objekt ObjectDataSource s názvem ProductsDataSourceDeclarative.

Vytvoření nového objektuDataSource s názvem ProductsDataSourceDeclarative

Obrázek 5: Vytvoření nového objektuDataSource s názvem ProductsDataSourceDeclarative (kliknutím zobrazíte obrázek v plné velikosti)

Nakonfigurujte ObjectDataSource tak, aby používal ProductsBLL třídu , a nastavte rozevírací seznam na kartě SELECT na GetProducts(). Na kartě UPDATE zvolte přetížení se třemi UpdateProduct vstupními parametry – productName, unitPricea productID. Na kartách VLOŽENÍ a ODSTRANIT nastavte rozevírací seznamy na (Žádný).

Použití přetížení UpdateProduct se třemi vstupními parametry

Obrázek 6: Použití přetížení UpdateProduct se třemi vstupními parametry (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte seznam Drop-Down na (Žádný) pro karty VLOŽENÍ a ODSTRANIT.

Obrázek 7: Nastavení seznamu Drop-Down na (Žádný) pro karty INSERT a DELETE (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce Konfigurovat zdroj dat vytvoří Visual Studio v zobrazení GridView pro každé z datových polí BoundFields a CheckBoxFields. Odeberte všechna pole kromě ProductName, CategoryNamea UnitPricenaformátujte je podle potřeby. V inteligentní značce GridView zaškrtněte políčka Povolit stránkování, Povolit řazení a Povolit úpravy. Visual Studio nastaví vlastnost ObjectDataSource na OldValuesParameterFormatStringoriginal_{0}. Aby funkce úprav objektu GridView fungovala správně, odeberte tuto vlastnost zcela z deklarativní syntaxe nebo ji nastavte zpět na výchozí hodnotu . {0}

Nakonec přidejte ovládací prvek Label Web nad GridView a nastavte jeho ID vlastnost na ODSEvents a jeho EnableViewState vlastnost na false. Po provedení těchto změn by deklarativní kód stránky měl vypadat nějak takto. Všimněte si, že jsem provedl řadu estetických přizpůsobení polí GridView, které nejsou nutné k předvedení funkce závislostí mezipaměti 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>

Dále vytvořte obslužnou rutinu události objectDataSource Selecting a přidejte do ní následující kód:

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

Vzpomeňte si, že událost ObjectDataSource se Selecting aktivuje pouze při načítání dat ze svého podkladového objektu. Pokud ObjectDataSource přistupuje k datům z vlastní mezipaměti, tato událost se neaktivuje.

Teď přejděte na tuto stránku prostřednictvím prohlížeče. Vzhledem k tomu, že jsme ještě neimplementovali ukládání do mezipaměti, měla by se při každé stránce, řazení nebo úpravě mřížky zobrazit text "Aktivována událost výběru, jak je znázorněno na obrázku 8.

Výběr objektu ObjectDataSource události se aktivuje pokaždé, když je objekt GridView stránkovaný, upravený nebo seřazený.

Obrázek 8: Událost ObjectDataSource se Selecting aktivuje pokaždé, když je objekt GridView stránkovaný, upravený nebo seřazený (kliknutím zobrazíte obrázek v plné velikosti).

Jak jsme viděli v kurzu Ukládání dat do mezipaměti pomocí ObjectDataSource , nastavení EnableCaching vlastnosti na true způsobí, že ObjectDataSource bude ukládat data do mezipaměti po dobu určenou jeho CacheDuration vlastností. ObjectDataSource má SqlCacheDependency také vlastnost , která přidá jednu nebo více závislostí mezipaměti SQL k datům uloženým v mezipaměti pomocí vzoru :

databaseName1:tableName1;databaseName2:tableName2;...

Kde databaseName je název databáze zadaný v atributu name elementu <add> v Web.configa tableName je název databázové tabulky. Chcete-li například vytvořit ObjectDataSource, který ukládá data do mezipaměti po neomezenou dobu na základě závislosti mezipaměti SQL s tabulky Northwind Products , nastavte vlastnost ObjectDataSource na EnableCachingtrue a jeho SqlCacheDependency vlastnost na NorthwindDB:Products .

Poznámka

Můžete použít závislost mezipaměti SQL a vypršení platnosti podle času tak, že nastavíte EnableCaching na true, CacheDuration na časový interval a SqlCacheDependency na názvy databází a tabulek. ObjectDataSource vyřadí svá data, když dojde k vypršení platnosti na základě času nebo když systém dotazování zaznamená, že se podkladová data databáze změnila, podle toho, co nastane dříve.

Objekt GridView v SqlCacheDependencies.aspx nástroji zobrazí data ze dvou tabulek – Products a Categories (pole product s CategoryName se načte pomocí operátoru JOIN ).Categories Proto chceme zadat dvě závislosti mezipaměti SQL: NorthwindDB:Products; NorthwindDB:Categories .

Konfigurace objektu ObjectDataSource pro podporu ukládání do mezipaměti pomocí závislostí mezipaměti SQL v produktech a kategoriích

Obrázek 9: Konfigurace objektu ObjectDataSource pro podporu ukládání do mezipaměti pomocí závislostí mezipaměti SQL na Products a Categories (Kliknutím zobrazíte obrázek v plné velikosti)

Po nakonfigurování objektu ObjectDataSource tak, aby podporoval ukládání do mezipaměti, přejděte znovu na stránku v prohlížeči. Znovu platí, že text "Výběr události aktivované" by se měl objevit při první návštěvě stránky, ale při stránkování, řazení nebo kliknutí na tlačítka Upravit nebo Zrušit by měl zminout. Je to proto, že po načtení dat do mezipaměti ObjectDataSource, zůstanou tam, dokud Products nejsou změněny nebo tabulky nebo Categories data aktualizována prostřednictvím GridView.

Po procházení mřížky a upozornění na chybějící text "Výběr události aktivovaného textu, otevřete nové okno prohlížeče a přejděte na kurz Základy v části Úpravy, vkládání a odstraňování (~/EditInsertDelete/Basics.aspx). Aktualizujte název nebo cenu produktu. Potom z prvního okna prohlížeče zobrazte jinou stránku dat, seřaďte mřížku nebo klikněte na tlačítko Upravit na řádku. Tentokrát by se měla znovu zobrazit událost výběru, protože se změnila podkladová data databáze (viz Obrázek 10). Pokud se text nezobrazí, chvíli počkejte a zkuste to znovu. Mějte na paměti, že služba dotazování kontroluje změny Products tabulky každých pollTime milisekund, takže mezi aktualizací podkladových dat a vyřazením dat v mezipaměti je prodleva.

Úprava tabulky Products (Produkty) vyřadí produktová data uložená v mezipaměti.

Obrázek 10: Úprava tabulky Products vyřadí data produktů uložená v mezipaměti (kliknutím zobrazíte obrázek v plné velikosti)

Krok 6: Práce s třídou prostřednictvímSqlCacheDependencykódu programu

Ukládání dat do mezipaměti v kurzu Architektura se zabývalo výhodami použití samostatné vrstvy ukládání do mezipaměti v architektuře oproti těsnému propojení ukládání do mezipaměti s objektem ObjectDataSource. V tomto kurzu jsme vytvořili ProductsCL třídu, která předvádí programovou práci s mezipamětí dat. Pokud chcete využít závislosti mezipaměti SQL ve vrstvě ukládání do mezipaměti, použijte SqlCacheDependency třídu .

V systému SqlCacheDependency dotazování musí být objekt přidružený ke konkrétnímu páru databáze a tabulky. Následující kód například vytvoří SqlCacheDependency objekt založený na tabulce databáze Products Northwind:

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

Dva vstupní parametry konstruktoru SqlCacheDependency s jsou názvy databáze a tabulky v uvedeném pořadí. Stejně jako u vlastnosti ObjectDataSource s SqlCacheDependency je použitý název databáze stejný jako hodnota zadaná v name atributu elementu <add> v Web.config. Název tabulky je skutečný název tabulky databáze.

Chcete-li přidružit SqlCacheDependency položku přidanou do mezipaměti dat, použijte jedno z Insert přetížení metody, které přijímají závislost. Následující kód přidá hodnotu do mezipaměti dat po neomezenou dobu, ale přidruží ji k objektu SqlCacheDependency v Products tabulce. Stručně řečeno, hodnota zůstane v mezipaměti, dokud nebude vyřazena z důvodu omezení paměti nebo protože systém dotazování zjistil, že Products se tabulka od uložení do mezipaměti změnila.

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

Třída Vrstva ProductsCL ukládání do mezipaměti aktuálně ukládá data z Products tabulky do mezipaměti s využitím vypršení 60 sekund podle času. Pojďme aktualizovat tuto třídu tak, aby místo toho používala závislosti mezipaměti SQL. Metoda ProductsCL třídy s AddCacheItem , která je zodpovědná za přidání dat do mezipaměti, aktuálně obsahuje následující kód:

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);
}

Aktualizujte tento kód tak, SqlCacheDependency aby místo MasterCacheKeyArray závislosti mezipaměti používal objekt:

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);
}

Chcete-li otestovat tuto funkci, přidejte GridView na stránku pod existující ProductsDeclarative GridView. Nastavte tento nový Objekt GridView ID na ProductsProgrammatic a prostřednictvím jeho inteligentní značky vytvořte vazbu k novému objektu ObjectDataSource s názvem ProductsDataSourceProgrammatic. Nakonfigurujte ObjectDataSource tak, aby používal ProductsCL třídu , a nastavte rozevírací seznamy na kartách SELECT a UPDATE na GetProducts a UpdateProductv uvedeném pořadí.

Konfigurace ObjectDataSource pro použití třídy ProductsCL

Obrázek 11: Konfigurace objektu ObjectDataSource pro použití ProductsCL třídy (kliknutím zobrazíte obrázek v plné velikosti)

V seznamu Drop-Down karet SELECT vyberte metodu GetProducts.

Obrázek 12: Výběr GetProducts metody ze seznamu select tab s Drop-Down (kliknutím zobrazíte obrázek v plné velikosti)

V seznamu Drop-Down karet UPDATE zvolte metodu UpdateProduct.

Obrázek 13: Výběr metody UpdateProduct ze seznamu Drop-Down karet UPDATE (kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce Konfigurovat zdroj dat vytvoří Visual Studio v zobrazení GridView pro každé z datových polí BoundFields a CheckBoxFields. Stejně jako u prvního objektu GridView přidaného na tuto stránku odeberte všechna pole kromě ProductName, CategoryNamea UnitPricenaformátujte tato pole podle potřeby. V inteligentní značce GridView zaškrtněte políčka Povolit stránkování, Povolit řazení a Povolit úpravy. Stejně jako u objektu ProductsDataSourceDeclarative ObjectDataSource nastaví ProductsDataSourceProgrammatic Visual Studio vlastnost ObjectDataSource OldValuesParameterFormatString na original_{0}. Aby funkce úprav objektu GridView fungovala správně, nastavte tuto vlastnost zpět na {0} (nebo úplně odeberte přiřazení vlastnosti z deklarativní syntaxe).

Po dokončení těchto úloh by měl výsledný deklarativní kód GridView a ObjectDataSource vypadat takto:

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

Pokud chcete otestovat závislost mezipaměti SQL ve vrstvě ukládání do mezipaměti, nastavte zarážku v ProductCL metodě třídy s AddCacheItem a pak spusťte ladění. Při první návštěvě SqlCacheDependencies.aspxby se zarážka měla zobrazit, protože se data poprvé požadují a umístí do mezipaměti. Dále přejděte na jinou stránku v zobrazení GridView nebo seřaďte jeden ze sloupců. To způsobí, že GridView znovu dotazuje data, ale data by měla být nalezena v mezipaměti, protože Products tabulka databáze nebyla změněna. Pokud se data v mezipaměti opakovaně nenašla, ujistěte se, že je v počítači k dispozici dostatek paměti, a zkuste to znovu.

Po procházení několika stránek objektu GridView otevřete druhé okno prohlížeče a přejděte na kurz Základy v části Úpravy, vkládání a odstraňování (~/EditInsertDelete/Basics.aspx). Aktualizujte záznam z tabulky Products a pak v prvním okně prohlížeče zobrazte novou stránku nebo klikněte na jedno z záhlaví řazení.

V tomto scénáři uvidíte jednu ze dvou věcí: buď dojde k dosažení zarážky, což znamená, že data uložená v mezipaměti byla vyřazena z důvodu změny v databázi; nebo se zarážka nenarazí, což znamená, že SqlCacheDependencies.aspx se teď zobrazují zastaralá data. Pokud se zarážka nedosáhne, je pravděpodobné, že se služba dotazování od změny dat ještě neaktivovala. Mějte na paměti, že služba dotazování kontroluje změny Products tabulky každých pollTime milisekund, takže mezi aktualizací podkladových dat a vyřazením dat v mezipaměti je prodleva.

Poznámka

Toto zpoždění se s větší pravděpodobností objeví při úpravách některého z produktů prostřednictvím objektu GridView v SqlCacheDependencies.aspx. V kurzu Architektura jsme přidali MasterCacheKeyArray závislost mezipaměti, abychom zajistili, že se data upravovaná pomocí ProductsCL metody třídy s UpdateProduct vyřadí z mezipaměti. Tuto závislost mezipaměti jsme však nahradili při úpravě AddCacheItem metody dříve v tomto kroku, a proto ProductsCL bude třída dál zobrazovat data uložená v mezipaměti, dokud systém dotazování změnu tabulky nepoznamená Products . V kroku 7 se podíváme MasterCacheKeyArray , jak znovu zavést závislost mezipaměti.

Krok 7: Přidružení více závislostí k položce v mezipaměti

Vzpomeňte MasterCacheKeyArray si, že závislost mezipaměti se používá k zajištění toho, aby se všechna data související s produktem vyřadila z mezipaměti, když se aktualizují všechny položky přidružené k mezipaměti. Metoda například GetProductsByCategoryID(categoryID) ukládá ProductsDataTables instance do mezipaměti pro každou jedinečnou hodnotu categoryID . Pokud se jeden z těchto objektů vyřadí, MasterCacheKeyArray závislost mezipaměti zajistí, že se odeberou i ostatní objekty. Bez této závislosti na mezipaměti existuje při změně dat uložených v mezipaměti možnost, že ostatní produktová data uložená v mezipaměti můžou být za aktuální. V důsledku toho je důležité udržovat MasterCacheKeyArray závislost mezipaměti při použití závislostí mezipaměti SQL. Metoda mezipaměti Insert dat však umožňuje pouze jeden objekt závislosti.

Při práci se závislostmi mezipaměti SQL navíc možná budeme muset jako závislosti přidružit více databázových tabulek. Například ProductsDataTable objekt uložený v mezipaměti ve ProductsCL třídě obsahuje názvy kategorií a dodavatelů pro každý produkt, ale AddCacheItem metoda používá pouze závislost na Products. V takové situaci, pokud uživatel aktualizuje název kategorie nebo dodavatele, zůstanou data produktů uložená v mezipaměti a budou za aktuální. Proto chceme, aby produktová data uložená v mezipaměti závisela nejen Products na tabulce, ale také na Categories tabulkách a Suppliers .

TřídaAggregateCacheDependency poskytuje prostředky pro přidružení více závislostí k položce mezipaměti. Začněte vytvořením AggregateCacheDependency instance. Dále přidejte sadu závislostí pomocí AggregateCacheDependency metody s Add . Při následném vložení položky do mezipaměti dat předejte AggregateCacheDependency instanci . Když se AggregateCacheDependency změní některá ze závislostí instance, položka uložená v mezipaměti se vyřadí.

Následující příklad ukazuje aktualizovaný kód pro metodu ProductsCL třídy s AddCacheItem . Metoda vytvoří MasterCacheKeyArray závislost mezipaměti spolu s SqlCacheDependency objekty pro Productstabulky , Categoriesa Suppliers . Všechny jsou sloučené do jednoho AggregateCacheDependency objektu s názvem aggregateDependencies, který se pak předá metodě Insert .

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);
}

Otestujte tento nový kód. Změny Productstabulek , Categoriesnebo Suppliers teď způsobí vyřazení dat uložených v mezipaměti. Kromě toho ProductsCL metoda třídy s UpdateProduct , která se volá při úpravách produktu prostřednictvím GridView, vyřazuje MasterCacheKeyArray závislost mezipaměti, což způsobí vyřazení ProductsDataTable mezipaměti a opětovné načtení dat při dalším požadavku.

Poznámka

Závislosti mezipaměti SQL je možné použít také s ukládáním výstupu do mezipaměti. Ukázku této funkce najdete v tématu Použití ASP.NET ukládání výstupu do mezipaměti s SQL Server.

Souhrn

Při ukládání dat databáze do mezipaměti data v ideálním případě zůstanou v mezipaměti, dokud se v databázi nezmění. V ASP.NET 2.0 je možné vytvářet a používat závislosti mezipaměti SQL v deklarativních i programových scénářích. Jednou z výzev tohoto přístupu je zjištění, kdy byla data změněna. Plné verze Microsoft SQL Server 2005 poskytují možnosti oznámení, které mohou aplikaci upozornit při změně výsledku dotazu. Pro Express Edition SQL Server 2005 a starší verze SQL Server, musí být místo toho použit systém dotazování. Nastavení potřebné infrastruktury dotazování je naštěstí poměrně jednoduché.

Všechno nejlepší na programování!

Další čtení

Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Marko Rangel, Teresa Murphy a Hilton Giesenow. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.