Použití závislostí mezipaměti SQL (VB)
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 se svým podkladovým zdrojem dat, což vede k zastaralým datům, která se uchovávají příliš dlouho, nebo aktuální data, jejichž platnost vypršela příliš brzy. Lepším přístupem je použít třídu SqlCacheDependency tak, aby data zůstala uložená v mezipaměti, dokud se jejich podkladová data v databázi SQL nezmění. V tomto kurzu se dozvíte, jak na to.
Úvod
Techniky ukládání do mezipaměti, které byly prozkoumány v části Ukládání dat do mezipaměti s objekty ObjectDataSource a Ukládání dat do mezipaměti v kurzech Architektura, používaly k vyřazení dat z mezipaměti po zadaném období vypršení platnosti na základě času. Tento přístup představuje nejjednodušší způsob, jak vyvážit zvýšení výkonu ukládání do mezipaměti a neaktuálnost dat. Když vyberete časový limit x sekund, vývojář stránky připustí, aby si mohl užívat výkonnostních výhod ukládání do mezipaměti pouze x sekund, ale může si odpočinout, že data nebudou nikdy 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 bylo prozkoumá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 kvůli snadnému 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 nebudou podkladová data v databázi změněna. pak by se mezipaměť vyřazovala. Tento přístup maximalizuje výkonnostní 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 změněna, a vyřadí odpovídající položky z mezipaměti. Před ASP.NET 2.0 byli za implementaci tohoto systému zodpovědní vývojáři stránek.
ASP.NET 2.0 poskytuje SqlCacheDependency
třídu a infrastrukturu potřebnou k určení, kdy v databázi došlo ke změně, 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ími 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. V tomto okamžiku jsou položky v mezipaměti přidružené k dotazu vyřazeny. Při dotazování databázový server udržuje informace o tom, kdy byly konkrétní tabulky naposledy aktualizovány. Modul runtime ASP.NET pravidelně dotazuje databázi, aby zkontroloval, jaké tabulky se od zadání do mezipaměti změnily. 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 roku 2005. Vzhledem k tomu, že tyto kurzy používají edici Express SQL Server 2005, zaměříme se na nastavení a používání možnosti dotazování. Další informace o možnostech oznámení SQL Server 2005 najdete v části Další informace 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
, notificationCreated
a changeId
. Tato tabulka obsahuje řádek pro každou tabulku, která obsahuje data, která může být potřeba použít v závislostech 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 zvýší s každou úpravou tabulky.
Kromě AspNet_SqlCacheTablesForChangeNotification
tabulky musí databáze také obsahovat triggery pro každou z tabulek, které se můžou objevit v závislostech mezipaměti SQL. Tyto triggery se spouštějí 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í data 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 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 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.exe
pří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
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 přepínače -ed
použijte -et
, například:
/* 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 v pubs
ScottsServer
systému , 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 Products
tabulek , Categories
a 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 databáze Microsoft SQL Server Express 2005, která se nachází ve App_Data
složce? Zjistil jsem, že nejjednodušším řešením 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.
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í windows.
Obrázek 1: Připojení k localhost\SQLExpress
serveru
Po připojení k serveru zobrazí Management Studio server a podsložky pro databáze, zabezpečení a tak dále. 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 s vaší webové aplikace 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 předem s identifikátorem GUID. Abyste při použití nástroje příkazového řádku aspnet_regsql.exe nemuseli zadávat tento dlouhý název databáze, přejmenujte databázi na název, který je pro člověka srozumitelnější, kliknutím pravým tlačítkem myši na právě připojenou databázi a zvolením možnosti Přejmenovat. Přejmenoval(a) jsem databázi na DataTutorials .
Obrázek 3: Přejmenování připojené databáze na název s více Human-Friendly
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 nástroji 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 prostřednictvím Průzkumníka serveru. Všimněte si nové tabulky (AspNet_SqlCacheTablesForChangeNotification
), nových uložených procedur a triggerů v Products
tabulkách , Categories
a Suppliers
.
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í, která se provádí 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 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ř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 nástroji AspNet_SqlCacheTablesForChangeNotification
. Zastaralé závislosti mezipaměti SQL se z mezipaměti vyřadí.
Nastavení pollTime
přináší 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 prodlevu mezi změnami back-endových dat a vyřazením souvisejících položek mezipaměti. Žádost o databázi 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
.
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
, unitPrice
a productID
. Na kartách VLOŽENÍ a ODSTRANIT nastavte rozevírací seznamy na (Žádný).
Obrázek 6: Použití přetížení UpdateProduct se třemi vstupními parametry (kliknutím zobrazíte obrázek v plné velikosti)
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
, CategoryName
a UnitPrice
naformá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 OldValuesParameterFormatString
original_{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 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 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.
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.config
a 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 EnableCaching
True
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 .
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.
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ímSqlCacheDependency
kó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:
Dim productsTableDependency As _
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.
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 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 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, SqlCacheDependency
aby místo MasterCacheKeyArray
závislosti mezipaměti používal 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
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 UpdateProduct
v uvedeném pořadí.
Obrázek 11: Konfigurace objektu ObjectDataSource pro použití ProductsCL
třídy (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 12: Výběr GetProducts
metody ze seznamu select tab s Drop-Down (kliknutím zobrazíte obrázek v plné velikosti)
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
, CategoryName
a UnitPrice
naformá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.aspx
by 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 to pravděpodobně proto, že služba dotazování se od změny dat ještě neaktivovala. Nezapomeňte, ž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 dochází ke zpoždění.
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
nástroji . V kurzu Ukládání dat do mezipaměti v části Architektura jsme přidali MasterCacheKeyArray
závislost mezipaměti, abychom zajistili, že se data upravovaná prostřednictvím 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
třída bude dál zobrazovat data uložená v mezipaměti, dokud systém dotazování změnu tabulky zaznamená Products
. V kroku 7 se dozvíme, jak znovu MasterCacheKeyArray
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, že se z mezipaměti vyřadí všechna data související s produkty, když se aktualizuje jakákoli jednotlivá položka, která je k ní přidružená. 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í data produktu uložená v mezipaměti mohou být za zastaralé. Proto je důležité, abychom při používání závislostí mezipaměti SQL udržovali MasterCacheKeyArray
závislost mezipaměti. Metoda datové mezipaměti s Insert
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 jako závislosti přidružit více databázových tabulek. Například ProductsDataTable
mezipaměť 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ém případě, pokud uživatel aktualizuje název kategorie nebo dodavatele, zůstanou data produktu uložená v mezipaměti v mezipaměti a nebudou aktuální. Proto chceme, aby data produktů uložená v mezipaměti byla závislá nejen Products
na tabulce, ale také na Categories
tabulkách a Suppliers
.
TřídaAggregateCacheDependency
poskytuje způsob 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 Products
tabulky , Categories
a Suppliers
. Všechny jsou sloučeny do jednoho AggregateCacheDependency
objektu s názvem aggregateDependencies
, který se pak předá do Insert
metody.
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. Products
Změny tabulek , Categories
nebo Suppliers
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 také možné 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 Server.
Souhrn
Při ukládání dat databáze do mezipaměti zůstanou data v ideálním případě v mezipaměti, dokud se v databázi neupraví. S 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. Jedním z výzev tohoto přístupu je zjištění, kdy se data změnila. Plné verze Microsoft SQL Server 2005 poskytují možnosti oznámení, které mohou aplikaci upozornit, když se změní výsledek dotazu. Pro express edici 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é.
Šť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í:
- Použití oznámení dotazů v Microsoft SQL Server 2005
- Vytvoření oznámení dotazu
- Ukládání do mezipaměti v ASP.NET pomocí
SqlCacheDependency
třídy - nástroj pro registraci ASP.NET SQL Server (
aspnet_regsql.exe
) - Přehled
SqlCacheDependency
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 najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty tohoto kurzu byli Marko Rangel, Teresa Murphy a Hilton Giesenow. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .