Używanie zależności pamięci podręcznej SQL (C#)
Autor : Scott Mitchell
Najprostszą strategią buforowania jest umożliwienie wygaśnięcia buforowanych danych po upływie określonego czasu. Jednak takie proste podejście oznacza, że buforowane dane nie utrzymują skojarzenia z bazowym źródłem danych, co powoduje, że nieaktualne dane są przechowywane zbyt długo lub bieżące dane, które wygasły zbyt szybko. Lepszym rozwiązaniem jest użycie klasy SqlCacheDependency, tak aby dane były buforowane do momentu zmodyfikowania ich danych bazowych w bazie danych SQL. W tym samouczku pokazano, jak to zrobić.
Wprowadzenie
Techniki buforowania zbadane w danych buforowania za pomocą obiektu ObjectDataSource i danych buforowania w samouczkach Architektura używały wygaśnięcia opartego na czasie, aby wykluczyć dane z pamięci podręcznej po określonym przedziale czasu. Takie podejście to najprostszy sposób równoważenia wzrostu wydajności buforowania na nieaktualność danych. Wybierając czas wygaśnięcia x sekund, deweloper strony przyznaje, że korzyści z wydajności buforowania przez tylko x sekund, ale mogą być łatwe, że jej dane nigdy nie będą przestarzałe dłużej niż maksymalnie x sekund. Oczywiście w przypadku danych statycznych x można przedłużyć do okresu istnienia aplikacji internetowej, tak jak zostało to zbadane w samouczku Buforowanie danych podczas uruchamiania aplikacji .
Podczas buforowania danych bazy danych często wybierany jest termin wygaśnięcia, ale często jest nieodpowiednim rozwiązaniem. W idealnym przypadku dane bazy danych pozostaną w pamięci podręcznej do momentu zmodyfikowania bazowych danych w bazie danych; tylko wtedy pamięć podręczna zostanie eksmitowana. Takie podejście maksymalizuje zalety wydajności buforowania i minimalizuje czas trwania nieaktualnych danych. Jednak w celu korzystania z tych korzyści musi istnieć system, który wie, kiedy bazowe dane bazy danych zostały zmodyfikowane i eksmituje odpowiednie elementy z pamięci podręcznej. Przed ASP.NET 2.0 deweloperzy stron byli odpowiedzialni za implementację tego systemu.
ASP.NET 2.0 zapewnia klasęSqlCacheDependency
i infrastrukturę niezbędną do określenia, kiedy w bazie danych wystąpiła zmiana, aby można było eksmitować odpowiednie buforowane elementy. Istnieją dwie techniki określania, kiedy dane bazowe uległy zmianie: powiadamianie i sondowanie. Po omówieniu różnic między powiadomieniami i sondowaniem utworzymy infrastrukturę niezbędną do obsługi sondowania, a następnie dowiesz się, jak używać SqlCacheDependency
klasy w scenariuszach deklaratywnych i programowych.
Informacje o powiadomieniach i sondowaniu
Istnieją dwie techniki, których można użyć do określenia, kiedy dane w bazie danych zostały zmodyfikowane: powiadomienie i sondowanie. Dzięki powiadomieniu baza danych automatycznie powiadamia środowisko uruchomieniowe ASP.NET, gdy wyniki określonego zapytania zostały zmienione od czasu ostatniego wykonania zapytania, w którym to momencie są eksmitowane buforowane elementy skojarzone z zapytaniem. W przypadku sondowania serwer bazy danych przechowuje informacje o ostatniej aktualizacji określonych tabel. Środowisko uruchomieniowe ASP.NET okresowo sonduje bazę danych, aby sprawdzić, które tabele uległy zmianie od czasu ich wprowadzenia do pamięci podręcznej. Te tabele, których dane zostały zmodyfikowane, mają skojarzone elementy pamięci podręcznej wykluczone.
Opcja powiadomienia wymaga mniejszej konfiguracji niż sondowanie i jest bardziej szczegółowa, ponieważ śledzi zmiany na poziomie zapytania, a nie na poziomie tabeli. Niestety powiadomienia są dostępne tylko w pełnych wersjach programu Microsoft SQL Server 2005 (tj. wydaniach innych niż Express). Można jednak użyć opcji sondowania dla wszystkich wersji programu Microsoft SQL Server z wersji od 7.0 do 2005. Ponieważ te samouczki korzystają z wersji Express SQL Server 2005, skoncentrujemy się na konfigurowaniu i używaniu opcji sondowania. Zapoznaj się z sekcją Dalsze informacje na końcu tego samouczka, aby uzyskać więcej zasobów dotyczących możliwości powiadamiania SQL Server 2005 r.
W przypadku sondowania należy skonfigurować bazę danych tak, aby zawierała tabelę o nazwie AspNet_SqlCacheTablesForChangeNotification
zawierającą trzy kolumny — tableName
, notificationCreated
i changeId
. Ta tabela zawiera wiersz dla każdej tabeli zawierającej dane, które mogą być potrzebne do użycia w zależności pamięci podręcznej SQL w aplikacji internetowej. Kolumna tableName
określa nazwę tabeli, określając notificationCreated
datę i godzinę dodania wiersza do tabeli. Kolumna changeId
jest typu int
i ma początkową wartość 0. Jej wartość jest zwiększana wraz z każdą modyfikacją tabeli.
Oprócz AspNet_SqlCacheTablesForChangeNotification
tabeli baza danych musi również uwzględniać wyzwalacze dla każdej z tabel, które mogą pojawiać się w zależności pamięci podręcznej SQL. Te wyzwalacze są wykonywane za każdym razem, gdy wiersz jest wstawiany, aktualizowany lub usuwany i zwiększa wartość tabeli changeId
w pliku AspNet_SqlCacheTablesForChangeNotification
.
Środowisko uruchomieniowe ASP.NET śledzi bieżącą changeId
wartość tabeli podczas buforowania danych przy użyciu SqlCacheDependency
obiektu. Baza danych jest okresowo sprawdzana, a wszystkie SqlCacheDependency
obiekty, których changeId
wartość różni się od wartości w bazie danych, są eksmitowane, ponieważ inna changeId
wartość wskazuje, że nastąpiła zmiana tabeli od czasu buforowania danych.
Krok 1. Eksplorowanieaspnet_regsql.exe
programu wiersza polecenia
W przypadku podejścia sondowania baza danych musi być skonfigurowana tak, aby zawierała infrastrukturę opisaną powyżej: wstępnie zdefiniowaną tabelę (AspNet_SqlCacheTablesForChangeNotification
), kilka procedur składowanych i wyzwalacze dla każdej z tabel, które mogą być używane w zależnościach pamięci podręcznej SQL w aplikacji internetowej. Te tabele, procedury składowane i wyzwalacze można tworzyć za pomocą programu aspnet_regsql.exe
wiersza polecenia , który znajduje się w folderze $WINDOWS$\Microsoft.NET\Framework\version
. Aby utworzyć tabelę AspNet_SqlCacheTablesForChangeNotification
i skojarzone procedury składowane, uruchom następujące polecenie w wierszu polecenia:
/* 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
Uwaga
Aby wykonać te polecenia, określone dane logowania bazy danych muszą znajdować się w db_securityadmin
rolach i db_ddladmin
.
Aby na przykład dodać infrastrukturę do sondowania do bazy danych usługi Microsoft SQL Server o nazwie na serwerze bazy danych o nazwie pubs
ScottsServer
przy użyciu uwierzytelniania systemu Windows, przejdź do odpowiedniego katalogu i w wierszu polecenia wprowadź:
aspnet_regsql.exe -S ScottsServer -E -d pubs -ed
Po dodaniu infrastruktury na poziomie bazy danych musimy dodać wyzwalacze do tych tabel, które będą używane w zależnościach pamięci podręcznej SQL. aspnet_regsql.exe
Ponownie użyj programu wiersza polecenia, ale określ nazwę tabeli za pomocą przełącznika -t
i zamiast używać -ed
przełącznika , -et
w następujący sposób:
/* 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
Aby dodać wyzwalacze do authors
tabel i titles
w pubs
bazie danych w usłudze ScottsServer
, użyj polecenia :
aspnet_regsql.exe -S ScottsServer -E -d pubs -t authors -et
aspnet_regsql.exe -S ScottsServer -E -d pubs -t titles -et
Na potrzeby tego samouczka dodaj wyzwalacze do Products
tabel , Categories
i Suppliers
. Przyjrzymy się konkretnej składni wiersza polecenia w kroku 3.
Krok 2. Odwoływanie się do bazy danych microsoft SQL Server 2005 Express Edition w programieApp_Data
Program aspnet_regsql.exe
wiersza polecenia wymaga nazwy bazy danych i serwera w celu dodania niezbędnej infrastruktury sondowania. Ale jaka jest nazwa bazy danych i serwera bazy danych microsoft SQL Server 2005 Express, która znajduje się w folderzeApp_Data
? Zamiast odnajdywać nazwy baz danych i serwerów, okazało się, że najprostszym podejściem jest dołączenie bazy danych do localhost\SQLExpress
wystąpienia bazy danych i zmiana nazwy danych przy użyciu SQL Server Management Studio. Jeśli na komputerze jest zainstalowana jedna z pełnych wersji programu SQL Server 2005, prawdopodobnie na komputerze jest już zainstalowana SQL Server Management Studio. Jeśli masz tylko wersję Express, możesz pobrać bezpłatną wersję Microsoft SQL Server Management Studio Express Edition.
Zacznij od zamknięcia programu Visual Studio. Następnie otwórz SQL Server Management Studio i wybierz połączenie z serwerem localhost\SQLExpress
przy użyciu uwierzytelniania systemu Windows.
Rysunek 1. Dołączanie do localhost\SQLExpress
serwera
Po nawiązaniu połączenia z serwerem program Management Studio wyświetli serwer i będzie miał podfoldery baz danych, zabezpieczeń i tak dalej. Kliknij prawym przyciskiem myszy folder Bazy danych i wybierz opcję Dołącz. Spowoduje to wyświetlenie okna dialogowego Dołączanie baz danych (zobacz Rysunek 2). Kliknij przycisk Dodaj i wybierz NORTHWND.MDF
folder bazy danych w folderze aplikacji App_Data
internetowej.
Rysunek 2. Dołączanie NORTHWND.MDF
bazy danych z App_Data
folderu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Spowoduje to dodanie bazy danych do folderu Databases. Nazwa bazy danych może być pełną ścieżką do pliku bazy danych lub pełną ścieżką poprzedzaną identyfikatorem GUID. Aby uniknąć konieczności wpisywania długiej nazwy bazy danych podczas korzystania z narzędzia wiersza polecenia aspnet_regsql.exe, zmień nazwę bazy danych na bardziej przyjazną dla człowieka, klikając prawym przyciskiem myszy bazę danych po prostu dołączoną i wybierając polecenie Zmień nazwę. Zmieniono nazwę bazy danych na DataTutorials .
Rysunek 3. Zmiana nazwy dołączonej bazy danych na bardziej Human-Friendly nazwa
Krok 3. Dodawanie infrastruktury sondowania do bazy danych Northwind
Teraz, po dołączeniu NORTHWND.MDF
bazy danych z App_Data
folderu, możemy dodać infrastrukturę sondowania. Zakładając, że nazwa bazy danych została zmieniona na DataTutorials, uruchom następujące cztery polecenia:
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 uruchomieniu tych czterech poleceń kliknij prawym przyciskiem myszy nazwę bazy danych w programie Management Studio, przejdź do podmenu Zadania i wybierz polecenie Odłącz. Następnie zamknij program Management Studio i otwórz ponownie program Visual Studio.
Po ponownym otwarciu programu Visual Studio przejdź do szczegółów bazy danych za pomocą Eksploratora serwera. Zanotuj nową tabelę (AspNet_SqlCacheTablesForChangeNotification
), nowe procedury składowane i wyzwalacze w Products
tabelach , Categories
i Suppliers
.
Rysunek 4. Baza danych zawiera teraz niezbędną infrastrukturę sondowania
Krok 4. Konfigurowanie usługi sondowania
Po utworzeniu wymaganych tabel, wyzwalaczy i procedur składowanych w bazie danych ostatnim krokiem jest skonfigurowanie usługi sondowania, która jest wykonywana przez Web.config
określenie baz danych do użycia i częstotliwości sondowania w milisekundach. Poniższe znaczniki sonduje bazę danych Northwind co sekundę.
<?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>
Wartość name
w elemecie <add>
( NorthwindDB ) kojarzy nazwę czytelną dla człowieka z określoną bazą danych. Podczas pracy z zależnościami pamięci podręcznej SQL musimy odwołać się do nazwy bazy danych zdefiniowanej tutaj, a także tabeli, na podstawie których są przechowywane dane w pamięci podręcznej. Zobaczymy, jak używać SqlCacheDependency
klasy do programowego kojarzenia zależności pamięci podręcznej SQL z buforowanych danych w kroku 6.
Po ustanowieniu zależności pamięci podręcznej SQL system sondowania połączy się z bazami danych zdefiniowanymi w <databases>
elementach co pollTime
milisekundy i wykona procedurę AspNet_SqlCachePollingStoredProcedure
składowaną. Ta procedura składowana — która została dodana z powrotem w kroku 3 przy użyciu aspnet_regsql.exe
narzędzia wiersza polecenia — zwraca tableName
wartości i changeId
dla każdego rekordu w programie AspNet_SqlCacheTablesForChangeNotification
. Nieaktualne zależności pamięci podręcznej SQL są eksmitowane z pamięci podręcznej.
Ustawienie pollTime
wprowadza kompromis między wydajnością a nieaktualnością danych. pollTime
Niewielka wartość zwiększa liczbę żądań do bazy danych, ale szybciej eksmituje nieaktualne dane z pamięci podręcznej. Większa pollTime
wartość zmniejsza liczbę żądań bazy danych, ale zwiększa opóźnienie między zmianą danych zaplecza a wykluczeniem powiązanych elementów pamięci podręcznej. Na szczęście żądanie bazy danych wykonuje prostą procedurę składowaną, która zwraca tylko kilka wierszy z prostej, lekkiej tabeli. Jednak eksperymentuj z różnymi pollTime
wartościami, aby znaleźć idealną równowagę między dostępem do bazy danych a nieaktualnością danych dla aplikacji. Najmniejsza pollTime
dozwolona wartość to 500.
Uwaga
Powyższy przykład zawiera pojedynczą pollTime
wartość w <sqlCacheDependency>
elemecie, ale opcjonalnie można określić pollTime
wartość w <add>
elemecie. Jest to przydatne, jeśli określono wiele baz danych i chcesz dostosować częstotliwość sondowania na bazę danych.
Krok 5. Deklaratywna praca z zależnościami pamięci podręcznej SQL
W krokach od 1 do 4 przyjrzeliśmy się, jak skonfigurować niezbędną infrastrukturę bazy danych i skonfigurować system sondowania. Dzięki tej infrastrukturze możemy teraz dodawać elementy do pamięci podręcznej danych ze skojarzona zależność pamięci podręcznej SQL przy użyciu technik programowych lub deklaratywnych. W tym kroku sprawdzimy, jak deklaratywnie pracować z zależnościami pamięci podręcznej SQL. W kroku 6 przyjrzymy się programowej metodzie.
Samouczek Buforowanie danych za pomocą obiektu ObjectDataSource omówił funkcje deklaratywnego buforowania obiektu ObjectDataSource. Po prostu ustawiając EnableCaching
właściwość na true
i CacheDuration
właściwość na jakiś interwał czasu, obiekt ObjectDataSource automatycznie buforuje dane zwrócone z jego obiektu bazowego dla określonego interwału. Obiekt ObjectDataSource może również używać co najmniej jednej zależności pamięci podręcznej SQL.
Aby zademonstrować użycie zależności pamięci podręcznej SQL deklaratywnie, otwórz SqlCacheDependencies.aspx
stronę w Caching
folderze i przeciągnij element GridView z przybornika do Projektant. Ustaw element GridView na ID
ProductsDeclarative
i z jego tagu inteligentnego wybierz powiązanie go z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceDeclarative
.
Rysunek 5. Tworzenie nowego obiektu ObjectDataSource Nazwane ProductsDataSourceDeclarative
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Skonfiguruj obiekt ObjectDataSource do użycia ProductsBLL
klasy i ustaw listę rozwijaną na karcie SELECT na GetProducts()
wartość . Na karcie UPDATE wybierz przeciążenie z trzema UpdateProduct
parametrami wejściowymi — productName
, unitPrice
i productID
. Ustaw listy rozwijane na wartość (Brak) na kartach INSERT i DELETE.
Rysunek 6. Użycie przeciążenia UpdateProduct z trzema parametrami wejściowymi (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 7. Ustawianie listy Drop-Down na (Brak) dla kart INSERT i DELETE (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy Kreatora konfigurowania źródła danych program Visual Studio utworzy pola BoundFields i CheckBoxFields w elemecie GridView dla każdego pola danych. Usuń wszystkie pola, ale ProductName
, CategoryName
i UnitPrice
i sformatuj te pola zgodnie z potrzebami. W tagu inteligentnym GridView zaznacz pola wyboru Włącz stronicowanie, Włącz sortowanie i Włącz edytowanie. Program Visual Studio ustawi właściwość ObjectDataSource na OldValuesParameterFormatString
original_{0}
. Aby funkcja edycji elementu GridView działała prawidłowo, usuń tę właściwość całkowicie ze składni deklaratywnej lub ustaw ją z powrotem na wartość domyślną . {0}
Na koniec dodaj kontrolkę Etykieta sieci Web nad kontrolką GridView i ustaw jej ID
właściwość na ODSEvents
i jej EnableViewState
właściwość na false
. Po wprowadzeniu tych zmian znacznik deklaratywny strony powinien wyglądać podobnie do poniższego. Należy pamiętać, że wprowadzono wiele dostosowań estetycznych w polach GridView, które nie są niezbędne do zademonstrowania funkcji zależności pamięci podręcznej 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>
Następnie utwórz procedurę obsługi zdarzeń dla zdarzenia ObjectDataSource Selecting
i dodaj w nim następujący kod:
protected void ProductsDataSourceDeclarative_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
ODSEvents.Text = "-- Selecting event fired";
}
Pamiętaj, że zdarzenie ObjectDataSource Selecting
jest uruchamiane tylko w przypadku pobierania danych z jego obiektu bazowego. Jeśli obiekt ObjectDataSource uzyskuje dostęp do danych z własnej pamięci podręcznej, to zdarzenie nie zostanie wyzwolone.
Teraz odwiedź tę stronę za pośrednictwem przeglądarki. Ponieważ jeszcze zaimplementowaliśmy jakiekolwiek buforowanie, za każdym razem, gdy strona, sortowanie lub edytowanie siatki strona powinna wyświetlić tekst "Wybranie zdarzenia wyzwolonego, jak pokazano na rysunku 8.
Rysunek 8. Zdarzenie ObjectDataSource Selecting
jest wyzwalane za każdym razem, gdy element GridView jest stronicowany, edytowany lub posortowany (kliknij, aby wyświetlić obraz pełnowymiarowy)
Jak pokazano w samouczku Buforowanie danych za pomocą obiektu ObjectDataSource , ustawienie EnableCaching
właściwości powoduje true
, że właściwość ObjectDataSource będzie buforować swoje dane przez czas określony przez jego CacheDuration
właściwość. Obiekt ObjectDataSource ma SqlCacheDependency
również właściwość, która dodaje co najmniej jedną zależność pamięci podręcznej SQL do buforowanych danych przy użyciu wzorca:
databaseName1:tableName1;databaseName2:tableName2;...
Gdzie databaseName to nazwa bazy danych określona w name
atrybucie <add>
elementu w , Web.config
a tableName jest nazwą tabeli bazy danych. Aby na przykład utworzyć obiekt ObjectDataSource, który buforuje dane na czas nieokreślony na podstawie zależności pamięci podręcznej SQL od tabeli Northwind s Products
, ustaw właściwość ObjectDataSource EnableCaching
na true
i jej SqlCacheDependency
właściwość na NorthwindDB:Products .
Uwaga
Można użyć zależności pamięci podręcznej SQL i wygaśnięcia opartego na czasie, ustawiając wartość EnableCaching
true
na , CacheDuration
na interwał czasu oraz SqlCacheDependency
na nazwy baz danych i tabeli. Obiekt ObjectDataSource wykluczy swoje dane po osiągnięciu wygaśnięcia opartego na czasie lub gdy system sondowania zauważa, że bazowe dane bazy danych uległy zmianie, w zależności od tego, co nastąpi wcześniej.
Element GridView w programie SqlCacheDependencies.aspx
wyświetla dane z dwóch tabel — Products
i Categories
(pole produktu CategoryName
jest pobierane za pośrednictwem elementu JOIN
.Categories
W związku z tym chcemy określić dwie zależności pamięci podręcznej SQL: NorthwindDB:Products; NorthwindDB:Categories .
Rysunek 9. Konfigurowanie obiektu ObjectDataSource do obsługi buforowania przy użyciu zależności Products
pamięci podręcznej SQL i Categories
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po skonfigurowaniu obiektu ObjectDataSource do obsługi buforowania ponownie przejdź do strony za pośrednictwem przeglądarki. Ponownie tekst "Wyzwolone zdarzenie wybierania powinno pojawić się podczas pierwszej wizyty na stronie, ale powinien odejść podczas stronicowania, sortowania lub klikania przycisków Edytuj lub Anuluj. Dzieje się tak dlatego, że po załadowaniu danych do pamięci podręcznej ObjectDataSource pozostają tam do momentu Products
modyfikacji tabel lub Categories
lub zaktualizowania danych za pośrednictwem kontrolki GridView.
Po stronicowaniu przez siatkę i zaniesieniu braku tekstu "Wybieranie zdarzenia wyzwolonego tekstu otwórz nowe okno przeglądarki i przejdź do samouczka Podstawy w sekcji Edytowanie, Wstawianie i Usuwanie (~/EditInsertDelete/Basics.aspx
). Zaktualizuj nazwę lub cenę produktu. Następnie w oknie pierwszej przeglądarki wyświetl inną stronę danych, posortuj siatkę lub kliknij przycisk Edytuj wiersz. Tym razem zdarzenie wyboru powinno zostać ponownie wyzwolone, ponieważ bazowe dane bazy danych zostały zmodyfikowane (patrz Rysunek 10). Jeśli tekst nie jest wyświetlany, poczekaj chwilę i spróbuj ponownie. Pamiętaj, że usługa sondowania sprawdza zmiany Products
w tabeli co pollTime
milisekundy, dlatego występuje opóźnienie między aktualizowaniem danych bazowych a eksmitowaniem buforowanych danych.
Rysunek 10. Modyfikowanie tabeli products eksmituje buforowane dane produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 6. Programowe praca z klasąSqlCacheDependency
W samouczku Buforowanie danych w architekturze przedstawiono korzyści wynikające z używania oddzielnej warstwy buforowania w architekturze, a nie ściśle sprzężenia buforowania z obiektem ObjectDataSource. W tym samouczku utworzyliśmy klasę ProductsCL
, która programowo współpracuje z pamięcią podręczną danych. Aby korzystać z zależności pamięci podręcznej SQL w warstwie buforowania, użyj SqlCacheDependency
klasy .
W systemie SqlCacheDependency
sondowania obiekt musi być skojarzony z określoną bazą danych i parą tabel. Na przykład poniższy kod tworzy SqlCacheDependency
obiekt na podstawie tabeli bazy danych Products
Northwind:
Caching.SqlCacheDependency productsTableDependency =
new Caching.SqlCacheDependency("NorthwindDB", "Products");
Dwa parametry SqlCacheDependency
wejściowe konstruktora to odpowiednio nazwy baz danych i tabel. Podobnie jak we właściwości ObjectDataSource SqlCacheDependency
, używana nazwa bazy danych jest taka sama jak wartość określona w name
atrybucie <add>
elementu w Web.config
. Nazwa tabeli to rzeczywista nazwa tabeli bazy danych.
Aby skojarzyć SqlCacheDependency
element z elementem dodanym do pamięci podręcznej danych, użyj jednego z Insert
przeciążeń metody akceptujących zależność. Poniższy kod dodaje wartość do pamięci podręcznej danych przez nieokreślony czas trwania, ale kojarzy go z tabelą SqlCacheDependency
Products
. Krótko mówiąc, wartość pozostanie w pamięci podręcznej, dopóki nie zostanie eksmitowana z powodu ograniczeń pamięci lub ponieważ system sondowania wykrył, że Products
tabela uległa zmianie od czasu jego buforowania.
Caching.SqlCacheDependency productsTableDependency =
new Caching.SqlCacheDependency("NorthwindDB", "Products");
Cache.Insert(key,
value,
productsTableDependency,
System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration);
Klasa warstwy ProductsCL
buforowania buforuje obecnie dane z Products
tabeli przy użyciu wygaśnięcia na podstawie czasu 60 sekund. Zaktualizujmy tę klasę, aby zamiast tego korzystała z zależności pamięci podręcznej SQL. Metoda ProductsCL
klasy s AddCacheItem
, która jest odpowiedzialna za dodawanie danych do pamięci podręcznej, obecnie zawiera następujący kod:
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);
}
Zaktualizuj ten kod, aby użyć SqlCacheDependency
obiektu zamiast zależności pamięci podręcznej MasterCacheKeyArray
:
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);
}
Aby przetestować tę funkcję, dodaj element GridView do strony poniżej istniejącej ProductsDeclarative
kontrolki GridView. Ustaw ten nowy element GridView na ID
ProductsProgrammatic
i, za pomocą tagu inteligentnego, powiąż go z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceProgrammatic
. Skonfiguruj obiekt ObjectDataSource do użycia ProductsCL
klasy, ustawiając listy rozwijane na kartach SELECT i UPDATE odpowiednio na GetProducts
i UpdateProduct
.
Rysunek 11. Konfigurowanie obiektu ObjectDataSource do używania ProductsCL
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 12. Wybierz metodę GetProducts
z listy Drop-Down SELECT Tab (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 13. Wybierz metodę UpdateProduct z listy Drop-Down kart AKTUALIZACJI (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy Kreatora konfigurowania źródła danych program Visual Studio utworzy pola BoundFields i CheckBoxFields w elemecie GridView dla każdego pola danych. Podobnie jak w przypadku pierwszego elementu GridView dodanego do tej strony, usuń wszystkie pola, ale ProductName
, CategoryName
i UnitPrice
sformatuj te pola zgodnie z potrzebami. W tagu inteligentnym GridView zaznacz pola wyboru Włącz stronicowanie, Włącz sortowanie i Włącz edytowanie. Podobnie jak w przypadku ProductsDataSourceDeclarative
obiektu ObjectDataSource, program Visual Studio ustawi ProductsDataSourceProgrammatic
właściwość ObjectDataSource OldValuesParameterFormatString
na original_{0}
. Aby funkcja edycji elementu GridView działała prawidłowo, ustaw tę właściwość z powrotem na {0}
(lub całkowicie usuń przypisanie właściwości ze składni deklaratywnej).
Po wykonaniu tych zadań wynikowe znaczniki deklaratywne GridView i ObjectDataSource powinny wyglądać następująco:
<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>
Aby przetestować zależność pamięci podręcznej SQL w warstwie buforowania, ustaw punkt przerwania w ProductCL
metodzie klasy s AddCacheItem
, a następnie rozpocznij debugowanie. Podczas pierwszej wizyty SqlCacheDependencies.aspx
punkt przerwania powinien zostać trafiony, ponieważ dane są żądane po raz pierwszy i umieszczone w pamięci podręcznej. Następnie przejdź do innej strony w elemecie GridView lub posortuj jedną z kolumn. Powoduje to ponowne zapytanie danych elementu GridView, ale dane powinny znajdować się w pamięci podręcznej, ponieważ Products
tabela bazy danych nie została zmodyfikowana. Jeśli dane nie znajdują się wielokrotnie w pamięci podręcznej, upewnij się, że na komputerze jest wystarczająca ilość pamięci i spróbuj ponownie.
Po stronicowaniu za pomocą kilku stron kontrolki GridView otwórz drugie okno przeglądarki i przejdź do samouczka Podstawy w sekcji Edytowanie, Wstawianie i Usuwanie (~/EditInsertDelete/Basics.aspx
). Zaktualizuj rekord z tabeli Products, a następnie w pierwszym oknie przeglądarki wyświetl nową stronę lub kliknij jeden z nagłówków sortowania.
W tym scenariuszu zobaczysz jedną z dwóch rzeczy: zostanie trafiony punkt przerwania wskazujący, że buforowane dane zostały eksmitowane z powodu zmiany w bazie danych; lub punkt przerwania nie zostanie trafiony, co oznacza, że SqlCacheDependencies.aspx
teraz pokazuje nieaktualne dane. Jeśli punkt przerwania nie zostanie trafiony, prawdopodobnie usługa sondowania nie została jeszcze wyzwolona od czasu zmiany danych. Pamiętaj, że usługa sondowania sprawdza zmiany Products
w tabeli co pollTime
milisekundy, dlatego występuje opóźnienie między aktualizowaniem danych bazowych a eksmitowaniem buforowanych danych.
Uwaga
To opóźnienie jest bardziej prawdopodobne podczas edytowania jednego z produktów za pośrednictwem kontrolki GridView w programie SqlCacheDependencies.aspx
. W samouczku Buforowanie danych w architekturze dodaliśmy MasterCacheKeyArray
zależność pamięci podręcznej, aby upewnić się, że dane edytowane za pomocą ProductsCL
metody klasy UpdateProduct
zostały wykluczone z pamięci podręcznej. Jednak ta zależność pamięci podręcznej została zastąpiona podczas modyfikowania AddCacheItem
metody wcześniej w tym kroku, a w związku z tym ProductsCL
klasa będzie nadal pokazywać buforowane dane, dopóki system sondowania nie zanotuje zmiany Products
w tabeli. Zobaczymy, jak przywrócić zależność pamięci podręcznej MasterCacheKeyArray
w kroku 7.
Krok 7. Kojarzenie wielu zależności z elementem buforowanym
Należy pamiętać, że MasterCacheKeyArray
zależność pamięci podręcznej służy do zapewnienia, że wszystkie dane związane z produktem są eksmitowane z pamięci podręcznej po zaktualizowaniu dowolnego elementu skojarzonego z nim. Na przykład GetProductsByCategoryID(categoryID)
metoda buforuje ProductsDataTables
wystąpienia dla każdej unikatowej wartości categoryID . Jeśli jeden z tych obiektów zostanie eksmitowany, MasterCacheKeyArray
zależność pamięci podręcznej gwarantuje również usunięcie pozostałych obiektów. Bez tej zależności pamięci podręcznej, gdy buforowane dane są modyfikowane, istnieje możliwość, że inne buforowane dane produktu mogą być nieaktualne. W związku z tym ważne jest, aby zachować zależność pamięci podręcznej MasterCacheKeyArray
podczas korzystania z zależności pamięci podręcznej SQL. Jednak metoda pamięci podręcznej Insert
danych zezwala tylko na pojedynczy obiekt zależności.
Ponadto podczas pracy z zależnościami pamięci podręcznej SQL może być konieczne skojarzenie wielu tabel bazy danych jako zależności. Na przykład ProductsDataTable
buforowany w ProductsCL
klasie zawiera nazwy kategorii i dostawców dla każdego produktu, ale AddCacheItem
metoda używa tylko zależności od Products
. W takiej sytuacji, jeśli użytkownik aktualizuje nazwę kategorii lub dostawcy, buforowane dane produktu pozostaną w pamięci podręcznej i będą nieaktualne. W związku z tym chcemy, aby buforowane dane produktu zależały nie tylko Products
od tabeli, ale także tabel Categories
i Suppliers
.
KlasaAggregateCacheDependency
zapewnia metodę kojarzenia wielu zależności z elementem pamięci podręcznej. Zacznij od utworzenia AggregateCacheDependency
wystąpienia. Następnie dodaj zestaw zależności przy użyciu AggregateCacheDependency
metody s Add
. Podczas wstawiania elementu do pamięci podręcznej danych następnie przekaż AggregateCacheDependency
wystąpienie. Gdy dowolna z AggregateCacheDependency
zależności wystąpienia ulegnie zmianie, buforowany element zostanie wykluczony.
Poniżej przedstawiono zaktualizowany kod ProductsCL
dla metody klasy s AddCacheItem
. Metoda tworzy zależność pamięci podręcznej MasterCacheKeyArray
wraz z obiektami SqlCacheDependency
dla Products
tabel , Categories
i Suppliers
. Wszystkie te elementy są łączone w jeden AggregateCacheDependency
obiekt o nazwie aggregateDependencies
, który następnie jest przekazywany do Insert
metody .
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);
}
Przetestuj ten nowy kod. Teraz zmiany w Products
tabelach , Categories
lub Suppliers
powodują eksmitowanie buforowanych danych. ProductsCL
Ponadto metoda klasy sUpdateProduct
, która jest wywoływana podczas edytowania produktu za pośrednictwem elementu GridView, eksmituje MasterCacheKeyArray
zależność pamięci podręcznej, co powoduje eksmitowanie buforowanej ProductsDataTable
pamięci podręcznej i ponowne pobieranie danych w następnym żądaniu.
Uwaga
Zależności pamięci podręcznej SQL mogą być również używane z buforowaniem danych wyjściowych. Aby zapoznać się z pokazem tej funkcji, zobacz: Używanie buforowania wyjściowego ASP.NET z SQL Server.
Podsumowanie
Podczas buforowania danych bazy danych dane pozostaną w pamięci podręcznej, dopóki nie zostaną zmodyfikowane w bazie danych. W przypadku ASP.NET 2.0 zależności pamięci podręcznej SQL można tworzyć i używać w scenariuszach deklaratywnych i programowych. Jednym z wyzwań związanych z tym podejściem jest odkrycie, kiedy dane zostały zmodyfikowane. Pełne wersje usługi Microsoft SQL Server 2005 zapewniają możliwości powiadomień, które mogą powiadamiać aplikację o zmianie wyniku zapytania. W przypadku wersji Express Edition SQL Server 2005 i starszych wersji SQL Server należy użyć systemu sondowania. Na szczęście skonfigurowanie niezbędnej infrastruktury sondowania jest dość proste.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Korzystanie z powiadomień o zapytaniach w usłudze Microsoft SQL Server 2005
- Tworzenie powiadomienia o kwerendzie
- Buforowanie w ASP.NET za pomocą
SqlCacheDependency
klasy - narzędzie rejestracji ASP.NET SQL Server (
aspnet_regsql.exe
) - Omówienie
SqlCacheDependency
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Recenzenci w tym samouczku to Marko Rangel, Teresa Murphy i Hilton Giesenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.