Sdílet prostřednictvím


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

od Scotta Mitchella

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 neudržují žádnou souvislost s podkladovým zdrojem dat, což vede k zastaralým datům, která jsou příliš dlouhá nebo aktuální data, jejichž platnost vypršela příliš brzy. Lepším přístupem je použít třídu SqlCacheDependency, aby data zůstala uložená v mezipaměti, dokud se 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 prověřované v ukládání dat do mezipaměti pomocí ObjectDataSource a ukládání dat do mezipaměti v kurzech Architektury používaly vypršení platnosti založené na čase k vyřazení dat z mezipaměti po zadaném období. Tento přístup je nejjednodušší způsob, jak vyvážit zvýšení výkonu ukládání do mezipaměti proti neaktuálnosti dat. Když vyberete časový limit x sekund, vývojář stránky využívá výhody ukládání do mezipaměti pouze x sekund, ale může si být jistá, že data nebudou nikdy zastaralá déle než maximálně x sekund. Samozřejmě, u statických dat lze x prodloužit na dobu životnosti webové aplikace, jak bylo zkoumáno 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 pro snadné použití často volí vypršení platnosti na základě času, ale často se jedná o nedostatečné řešení. V ideálním případě by data databáze zůstala uložená v mezipaměti, dokud se podkladová data v databázi nezmění; pouze pak se mezipaměť vyřadí. Tento přístup maximalizuje výhody výkonu ukládání do mezipaměti a minimalizuje dobu trvání zastaralých dat. Aby se však tyto výhody mohly využívat, musí existovat nějaký 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 zodpovídali vývojáři stránek za implementaci tohoto systému.

ASP.NET 2.0 poskytuje SqlCacheDependency třídu a potřebnou infrastrukturu k 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í dva způsoby, jak určit, kdy se podkladová data změnila: oznámení a dotazování. Po diskusi o rozdílech mezi oznámením a dotazováním vytvoříme infrastrukturu potřebnou k podpoře dotazování a pak prozkoumáme, jak používat SqlCacheDependency třídu 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 upravena: oznámení a dotazování. Při oznámení 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. V tomto okamžiku se vyřadí položky uložené v mezipaměti přidružené k dotazu. Při dotazování databázový server uchovává informace o tom, kdy byly konkrétní tabulky naposledy aktualizovány. Modul runtime ASP.NET pravidelně dotazuje databázi, aby zkontrolovala, které tabulky se od jejich vstupu do mezipaměti změnily. Tyto tabulky, jejichž data byla změněna, mají přidružené položky mezipaměti vyřazeny.

Možnost oznámení vyžaduje menší 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 dostupná pouze v úplných edicích Microsoft SQL Serveru 2005 (tj. v jiných edicích než Express). Možnost dotazování se ale dá použít pro všechny verze Microsoft SQL Serveru od 7.0 do 2005. Vzhledem k tomu, že tyto kurzy používají edici Express SQL Serveru 2005, zaměříme se na nastavení a použití možnosti dotazování. Další informace o možnostech oznámení SQL Serveru 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 tři sloupce – tableName, notificationCreateda changeId. Tato tabulka obsahuje řádek pro každou tabulku, která obsahuje data, která by mohla být potřeba použít v závislosti mezipaměti SQL ve webové aplikaci. Sloupec tableName určuje název tabulky, zatímco 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 zvýší o každou změnu tabulky.

Kromě AspNet_SqlCacheTablesForChangeNotification tabulky musí databáze obsahovat také triggery pro každou z tabulek, které se mohou 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 rozdílná changeId hodnota označuje, že od uložení dat do mezipaměti došlo ke změně tabulky.

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

Při přístupu k dotazování 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 můžou 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:

Pokud mají být tyto příkazy spuštěny, musí být zadané přihlášení k databázi v rolích db_securityadmin a db_ddladmin.

Například pokud chcete přidat infrastrukturu pro průzkum do databáze Microsoft SQL Server pojmenované pubs na databázovém serveru pojmenovaném 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 použijí v závislostech mezipaměti SQL. Znovu použijte program příkazového řádku aspnet_regsql.exe, ale zadejte název tabulky pomocí přepínače -t a místo toho použijte -ed namísto -et, následovně:

/* 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 tabulek authors a titles v databázi na serveru pubs, 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 tabulek Products, Categories a Suppliers. V kroku 3 se podíváme na konkrétní syntaxi příkazového řádku.

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

Program aspnet_regsql.exe příkazového řádku vyžaduje název databáze a serveru, aby bylo možné 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 zjistit 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í aplikace SQL Server Management Studio. Pokud máte na počítači nainstalovanou jednu z úplných verzí SYSTÉMU SQL Server 2005, pravděpodobně už máte na počítači nainstalovanou aplikaci SQL Server Management Studio. Pokud máte jenom edici Express, můžete si stáhnout bezplatnou aplikaci Microsoft SQL Server Management Studio.

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

Připojení k localhost\SQLExpress Serveru

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

Po připojení k serveru zobrazí Management Studio server a bude obsahovat 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. Tím se zobrazí 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 webové aplikace App_Data .

Připojte databázi NORTHWND.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 s plnou velikostí)

Tím se databáze přidá do složky Databáze. Název databáze může být úplná cesta k databázovému souboru nebo úplná cesta předpřipravená identifikátorem GUID. Pokud se chcete vyhnout zadávání tohoto dlouhého názvu databáze při použití nástroje příkazového řádku aspnet_regsql.exe, přejmenujte databázi na popisnější název tak, že kliknete pravým tlačítkem myši na databázi, která je právě připojená a zvolíte Přejmenovat. Přejmenoval(a) jsem databázi na DataTutorials .

Přejmenujte připojenou databázi na název Více Human-Friendly

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

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

Teď, když jsme databázi připojili NORTHWND.MDF 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 sadě Management Studio, přejděte do podnabídky Úlohy a zvolte Odpojit. Pak zavřete Management Studio a znovu otevřete Visual Studio.

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

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

Obrázek 4: Databáze teď obsahuje 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) spojuje čitelný název pro člověka s konkrétní databází. Při práci se závislostmi mezipaměti SQL budeme muset odkazovat na zde definovaný název databáze a také na tabulku založenou na datech uložených v mezipaměti. V kroku 6 se dozví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řipojuje k databázím definovaným v prvcích <databases> každých pollTime milisekund a provede uloženou proceduru AspNet_SqlCachePollingStoredProcedure. Tato uložená procedura – která byla vložena v kroku 3 pomocí nástroje příkazového aspnet_regsql.exe řádku – vrátí hodnoty tableName a changeId pro každý záznam v AspNet_SqlCacheTablesForChangeNotification. Zastaralé závislosti mezipaměti SQL se z mezipaměti vyřadí.

Toto pollTime nastavení představuje kompromis mezi výkonem a neakutností dat. Malá pollTime hodnota zvyšuje počet požadavků na databázi, ale rychleji vyřadí zastaralá data z mezipaměti. Větší pollTime hodnota snižuje počet žádostí o databázi, ale zvyšuje zpoždění mezi tím, kdy se back-endová data změní a kdy se vyřadí související položky mezipaměti. Naštěstí požadavek na databázi spouští jednoduchou uloženou proceduru, která vrací jen několik řádků z jednoduché, zjednodušené tabulky. Ale experimentujte s různými pollTime hodnotami, abyste našli ideální rovnováhu mezi přístupem k databázi a neautností dat pro vaši aplikaci. pollTime Nejmenší povolená hodnota je 500.

Poznámka:

Výše uvedený příklad poskytuje jednu pollTime hodnotu v elementu <sqlCacheDependency>, ale volitelně můžete zadat hodnotu pollTime 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, jak nastavit potřebnou infrastrukturu databáze a nakonfigurovat systém dotazování. S touto infrastrukturou teď můžeme přidat 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 se podíváme, jak deklarativním způsobem 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á z příslušného objektu pro zadaný interval. ObjectDataSource může také použít jednu nebo více závislostí mezipaměti SQL.

Pokud chcete předvést použití závislostí mezipaměti SQL deklarativním způsobem, otevřete SqlCacheDependencies.aspx stránku ve Caching složce a přetáhněte Objekt GridView ze sady nástrojů do Návrháře. Nastavte Objekt GridView na IDProductsDeclarative a z jeho inteligentní značky zvolte, že se má svázat s novým ObjectDataSource s názvem ProductsDataSourceDeclarative.

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

Obrázek 5: Vytvoření nového objektu ObjectDataSource s názvem ProductsDataSourceDeclarative (kliknutím zobrazíte obrázek s plnou velikostí)

Nakonfigurujte ObjectDataSource pro použití ProductsBLL třídy a nastavte rozevírací seznam na kartě SELECT na GetProducts(). Na kartě UPDATE zvolte UpdateProduct přetížení se třemi vstupními parametry - productName, unitPricea productID. Nastavte rozevírací seznamy na (Žádné) na kartách INSERT a DELETE.

Použijte přetížení UpdateProduct s 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 s plnou velikostí)

Nastavte seznam Drop-Down na (žádný) pro karty INSERT a DELETE.

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 konfigurací zdroje dat vytvoří Visual Studio v objektu GridView pro každé z datových polí pole typu BoundField a CheckBoxField. Odeberte všechna pole kromě ProductName, CategoryName a UnitPrice a tyto pole naformátujte podle svého uvážení. Z panelu funkcí GridView zaškrtněte políčka pro povolení stránkování, povolení řazení a povolení úprav. Visual Studio nastaví vlastnost ObjectDataSource OldValuesParameterFormatString na original_{0}. Aby funkce úprav GridView s 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í zápis stránky měl vypadat podobně jako následující. Všimněte si, že jsem provedl řadu estetických přizpůsobení polí GridView, které nejsou nezbytné 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 pro událost ObjectDataSource Selecting a do ní přidejte následující kód:

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

Vzpomeňte si, že událost ObjectDataSource Selecting se aktivuje pouze při načítání dat z příslušné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 v prohlížeči. Vzhledem k tomu, že jsme dosud neimplementovali žádné ukládání do mezipaměti, měl by se při každém stránkování, třídění nebo úpravě mřížky zobrazit text "Výběrová událost byla spuštěna," jak ukazuje obrázek 8.

Událost Selecting objektu ObjectDataSource se spustí pokaždé, když se objekt GridView stránkuje, upravuje nebo třídí.

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

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

databaseName1:tableName1;databaseName2:tableName2;...

Where databaseName je název databáze, jak je uvedeno v name atributu <add> elementu v Web.configa tableName je název databázové tabulky. Chcete-li například vytvořit ObjectDataSource, který ukládá data do mezipaměti na neurčito na základě závislosti mezipaměti SQL vůči tabulce Northwind s Products, nastavte vlastnost ObjectDataSource na EnableCaching a jeho vlastnost True na NorthwindDB:Products.

Poznámka:

Můžete použít závislost mezipaměti SQL a vypršení na základě času nastavením EnableCaching na True, CacheDuration na časový interval a SqlCacheDependency na název(y) databáze a tabulky/tabulek. ObjectDataSource vyřadí data při dosažení vypršení časového limitu nebo když systém dotazování zjistí, že se podkladová data databáze změnila, podle toho, co nastane dříve.

GridView v SqlCacheDependencies.aspx zobrazuje data ze dvou tabulek - Products a Categories (pole produktu CategoryName je získáno pomocí JOIN na Categories). Proto chceme zadat dvě závislosti mezipaměti SQL: NorthwindDB:Products; NorthwindDB:Categories .

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

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

Po nakonfigurování ObjectDataSource pro podporu ukládání do mezipaměti se znovu přejděte na stránku prostřednictvím prohlížeče. Text 'Událost výběru aktivována' by se měl zobrazit při první návštěvě stránky, ale měl by zmizet při stránkování, řazení nebo kliknutí na tlačítka Upravit nebo Zrušit. Důvodem je to, že jakmile se data načtou do mezipaměti ObjectDataSource, zůstanou tam, dokud nebudou upraveny tabulky Products nebo Categories, či dokud se data neaktualizují prostřednictvím GridView.

Po procházení mřížky a zjištění absence textu pro událost výběru, otevřete nové okno prohlížeče a přejděte na kurz Základy v sekci Upravit, Vložit a Odstranit (~/EditInsertDelete/Basics.aspx). Aktualizujte název nebo cenu produktu. Potom v prvním okně prohlížeče zobrazte jinou stránku dat, seřaďte mřížku nebo klikněte na tlačítko Upravit řádek. Tentokrát by se měla znovu spustit událost vyvolání výběru, protože došlo ke změně podkladových dat databáze, viz obrázek 10. Pokud se text nezobrazí, chvíli počkejte a zkuste to znovu. Nezapomeňte, že služba dotazování kontroluje změny Products v tabulce v každém pollTime milisekundách, takže mezi aktualizací podkladových dat a vyřazením dat uložených v mezipaměti dochází ke zpoždění.

Úprava tabulky Produkty vyřadí data produktů uložených v mezipaměti.

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

Krok 6: Práce sSqlCacheDependencytřídou prostřednictvím kódu programu

V tutoriálu Ukládání dat do mezipaměti v architektuře jsme se podívali na výhody použití samostatné vrstvy ukládání do mezipaměti v architektuře oproti úzkému propojení ukládání do mezipaměti s ObjectDataSource. V tomto kurzu jsme vytvořili ProductsCL třídu, abychom demonstrovali práci s mezipamětí dat prostřednictvím programování. Pokud chcete využívat závislosti mezipaměti SQL ve vrstvě ukládání do mezipaměti, použijte SqlCacheDependency třídu.

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

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

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

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

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

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

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

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

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

Pokud chcete tuto funkci otestovat, přidejte objekt GridView na stránku pod existujícím ProductsDeclarative objektem GridView. Nastavte tuto novou vlastnost GridView na IDProductsProgrammatic a prostřednictvím její inteligentní značky vytvořte vazbu na nový ObjectDataSource s názvem ProductsDataSourceProgrammatic. Nakonfigurujte ObjectDataSource tak, aby používal ProductsCL třídu, 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 ObjectDataSource pro použití ProductsCL třídy (kliknutím zobrazíte obrázek s plnou velikostí)

Vyberte metodu GetProducts ze seznamu Drop-Down panelu SELECT.

Obrázek 12: Vyberte metodu z karty SELECT ze seznamu Drop-Down (GetProducts).

V seznamu Drop-Down karet UPDATE zvolte metodu UpdateProduct.

Obrázek 13: Vyberte metodu UpdateProduct ze seznamu karty UPDATE Drop-Down (Kliknutím zobrazíte obrázek s plnou velikostí)

Po dokončení průvodce konfigurací zdroje dat vytvoří Visual Studio v objektu GridView pro každé z datových polí pole typu BoundField a CheckBoxField. Stejně jako u prvního objektu GridView přidaného na tuto stránku odeberte všechna pole kromě ProductName, CategoryName a UnitPrice, a naformátujte tato pole jak uznáte za vhodné. Z panelu funkcí GridView zaškrtněte políčka pro povolení stránkování, povolení řazení a povolení úprav. Stejně jako u ProductsDataSourceDeclarative ObjectDataSource, Visual Studio nastaví vlastnost ProductsDataSourceProgrammaticOldValuesParameterFormatString na hodnotu original_{0}. Aby funkce úprav GridView s fungovala správně, nastavte tuto vlastnost zpět ( {0} nebo odeberte přiřazení vlastnosti z deklarativní syntaxe úplně).

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 na mezipaměti SQL ve vrstvě ukládání do mezipaměti, nastavte zarážku v metodě třídy ProductCLAddCacheItem a pak začněte ladit. Při první návštěvě SqlCacheDependencies.aspx by se měl bod přerušení zobrazit, protože jsou data požadována poprvé a umístí se do mezipaměti. V dalším kroku přejděte na jinou stránku v objektu GridView nebo seřaďte jeden ze sloupců. To způsobí, že GridView znovu dotazuje svá data, ale data by se měla najít 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 stránkování několika stránek objektu GridView otevřete druhé okno prohlížeče a přejděte do kurzu Základy v části Úpravy, Vložení a Odstranění (~/EditInsertDelete/Basics.aspx). Aktualizujte záznam z tabulky Products (Produkty) a potom v prvním okně prohlížeče zobrazte novou stránku nebo klikněte na některé ze záhlaví řazení.

V tomto scénáři uvidíte jednu ze dvou věcí: buď bude zarážka zachycena, což znamená, že data uložená v mezipaměti byla odstraněna kvůli změně v databázi; nebo zarážka nebude zachycena, což znamená, že SqlCacheDependencies.aspx teď zobrazuje zastaralá data. Pokud není dosaženo zarážky, je pravděpodobné, že se služba dotazování ještě nespustila poté, co byla data změněna. Nezapomeňte, že služba dotazování kontroluje změny Products v tabulce v každém pollTime milisekundách, takže mezi aktualizací podkladových dat a vyřazením dat uložených v mezipaměti dochází ke zpoždění.

Poznámka:

Toto zpoždění se pravděpodobně zobrazí při úpravě některého z produktů prostřednictvím GridView v SqlCacheDependencies.aspx. V části Ukládání dat do mezipaměti v kurzu Architektura jsme přidali MasterCacheKeyArray závislost mezipaměti, abychom zajistili, že data upravovaná prostřednictvím ProductsCL metody třídy s UpdateProduct byla vyřazena 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 třída bude nadále zobrazovat data uložená v mezipaměti, dokud systém dotazování nepopíše změnu Products tabulky. V kroku 7 uvidíme, jak znovu zavést MasterCacheKeyArray závislost mezipaměti.

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

Vzpomeňte si, že MasterCacheKeyArray 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 aktualizuje jakákoliv jedna položka přidružená k ní. Například GetProductsByCategoryID(categoryID) metoda ukládá instance do mezipaměti ProductsDataTables pro každou jedinečnou hodnotu categoryID . Pokud se některý z těchto objektů vyřadí, MasterCacheKeyArray závislost mezipaměti zajistí, že se odeberou i ostatní. Bez této závislosti mezipaměti, když se data uložená v mezipaměti změní, je možné, že produktová data v mezipaměti zastarávají. Proto je důležité udržovat závislost mezipaměti MasterCacheKeyArray při použití závislostí SQL mezipaměti. 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 může být potřeba přidružit několik databázových tabulek jako závislostí. Například ProductsDataTable mezipaměť uložená ve třídě ProductsCL obsahuje názvy kategorií a dodavatelů pro každý produkt, ale metoda AddCacheItem používá pouze závislost na Products. V takovém případě, pokud uživatel aktualizuje název kategorie nebo dodavatele, data produktů uložených v mezipaměti zůstanou v mezipaměti a budou zastaralé. Proto chceme, aby data produktů uložená v mezipaměti závisela nejen na Products tabulce, ale také na Categories tabulkách a Suppliers tabulkách.

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 přidání položky do mezipaměti dat předáte instanci AggregateCacheDependency. Když se změní jakákoliAggregateCacheDependency závislost instance, položka uložená v mezipaměti se vyřadí.

Následující příklad ukazuje aktualizovaný kód pro třídu ProductsCL a metodu AddCacheItem Metoda vytvoří MasterCacheKeyArray závislost mezipaměti spolu s SqlCacheDependency objekty pro Products, Categories a Suppliers tabulky. Všechny se zkombinují do jednoho AggregateCacheDependency objektu s názvem aggregateDependencies, který se pak předá metodě Insert .

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

Otestujte tento nový kód. Teď změny v tabulkách Products, Categories nebo Suppliers způsobí vyřazení dat uložených v mezipaměti. Kromě toho metoda ProductsCL třídy UpdateProduct, která je volána při úpravě produktu prostřednictvím GridView, vyřazuje závislost na mezipaměti MasterCacheKeyArray, což způsobí, že je mezipaměť ProductsDataTable vyprázdněna a data jsou při dalším požadavku znovu načtena.

Poznámka:

Závislosti mezipaměti SQL lze také použít 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 Serverem.

Shrnutí

Při ukládání dat databáze do mezipaměti budou data v ideálním případě zůstat v mezipaměti, dokud se nezmění v databázi. S ASP.NET 2.0 je možné vytvořit a použít závislosti mezipaměti SQL v deklarativních i programových scénářích. Jedním z problémů s tímto přístupem je zjištění, kdy byla data upravena. Úplné verze Microsoft SQL Serveru 2005 poskytují možnosti oznámení, které můžou upozornit aplikaci při změně výsledku dotazu. V případě edice Express SYSTÉMU SQL Server 2005 a starších verzí SYSTÉMU SQL Server je nutné místo toho použít systém dotazování. Nastavení nezbytné infrastruktury dotazování je naštěstí poměrně jednoduché.

Šťastné 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 ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Nauč se ASP.NET 2.0 za 24 hodin. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí recenzenti tohoto kurzu byli Marko Rangel, Teresa Murphy a Hilton Giesenow. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.