Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
Najprostszą strategią buforowania jest umożliwienie wygaśnięcia buforowanych danych po określonym przedziale czasu. Jednak takie proste podejście oznacza, że buforowane dane nie są skojarzone ze swoim bazowym źródłem danych, co powoduje, że nieaktualne dane przechowywane są zbyt długo lub bieżące dane zostają zbyt szybko uznane za przestarzałe. Lepszym rozwiązaniem jest użycie klasy SqlCacheDependency, tak aby dane były buforowane do momentu modyfikacji danych bazowych w bazie danych SQL. Ten samouczek pokazuje, jak to zrobić.
Wprowadzenie
Techniki buforowania zbadane w buforowaniu danych za pomocą obiektu ObjectDataSource i buforowaniu danych w Architekturze w samouczkach używały wygaśnięcia opartego na czasie, aby usunąć dane z pamięci podręcznej po określonym przedziale czasu. Takie podejście jest najprostszym sposobem na zrównoważenie korzyści płynących z buforowania przy jednoczesnym zmniejszeniu ryzyka nieaktualności danych. Po wybraniu czasu wygaśnięcia wynoszącego x sekund, deweloper strony zgadza się cieszyć korzyściami płynącymi z buforowania przez jedynie x sekund, ale może być spokojny, że dane nigdy nie będą przestarzałe dłużej niż maksymalnie x sekund. Oczywiście w przypadku danych statycznych x można rozszerzyć na okres istnienia aplikacji internetowej, jak pokazano w samouczku Buforowanie danych podczas uruchamiania aplikacji .
Podczas buforowania danych z bazy danych, wygaśnięcie zależne od czasu jest często wybierane ze względu na łatwość użycia, ale okazuje się często niewystarczającym rozwiązaniem. W idealnym przypadku dane w bazie pozostałyby w pamięci podręcznej do momentu ich zmiany w bazie; tylko wtedy pamięć podręczna zostałaby usunięta. Takie podejście maksymalizuje korzyści z wydajności buforowania i minimalizuje czas trwania nieaktualnych danych. Jednak w celu korzystania z tych korzyści musi istnieć pewien 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 udostępnia klasę i niezbędną SqlCacheDependency infrastrukturę do określenia, kiedy nastąpiła zmiana w bazie danych, 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 informuje środowisko uruchomieniowe ASP.NET o zmianie wyników określonego zapytania od czasu jego ostatniego wykonania, po czym buforowane elementy skojarzone z zapytaniem są usuwane. Podczas 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. Tabele, których dane zostały zmodyfikowane, mają skojarzone elementy pamięci podręcznej usunięte.
Opcja powiadomienia wymaga mniejszej konfiguracji niż sondowania 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. w wersjach 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 programu 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 powiadomień programu SQL Server 2005.
W przypadku sondowania baza danych musi być skonfigurowana tak, aby zawierała tabelę o nazwie AspNet_SqlCacheTablesForChangeNotification zawierającą trzy kolumny — tableName, notificationCreatedi 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. Jego wartość jest zwiększana wraz z każdą modyfikacją tabeli.
Oprócz tabeli AspNet_SqlCacheTablesForChangeNotification, baza danych musi również zawierać wyzwalacze dla każdej z tabel, które mogą pojawić się w SQL cache dependency. Te wyzwalacze są wykonywane za każdym razem, gdy wiersz jest wstawiany, aktualizowany lub usuwany i zwiększają wartość tabeli changeId w elemencie 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.exeprogramu 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 wyzwalaczy 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 utworzyć za pomocą programu wiersza polecenia aspnet_regsql.exe, 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 polecenia w terminalu.
/* 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 / Notatka
Aby wykonać te polecenia, określone dane logowania bazy danych muszą znajdować się w rolach db_securityadmin i db_ddladmin.
Aby na przykład dodać infrastrukturę do mechanizmu ankietowania do bazy danych programu Microsoft SQL Server o nazwie pubs na serwerze bazy danych o nazwie ScottsServer, używając 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 przy użyciu przełącznika -t, a zamiast przełącznika -ed użyj -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 tabel authors i titles w bazie danych pubs na ScottsServer, użyj:
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 tabel Products, Categories i Suppliers. Przyjrzymy się konkretnej składni wiersza polecenia w kroku 3.
Krok 2. Odwoływanie się do bazy danych programu 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 programu Microsoft SQL Server 2005 Express, która znajduje się w folderze App_Data ? Zamiast odkrywać, czym są 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 programu SQL Server Management Studio. Jeśli na komputerze jest zainstalowana jedna z pełnych wersji programu SQL Server 2005, prawdopodobnie na komputerze jest już zainstalowany program 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 program SQL Server Management Studio i wybierz opcję nawiązania połączenia 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 (patrz 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. Zmień nazwę dołączonej bazy danych na bardziej odpowiednią nazwę Human-Friendly
Krok 3. Dodawanie infrastruktury sondowania do bazy danych Northwind
Teraz, gdy dołączyliśmy bazę danych z folderu NORTHWND.MDF, jesteśmy gotowi, aby dodać infrastrukturę do sondowania. Zakładając, że zmieniono nazwę bazy danych 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 bazy danych za pomocą Eksploratora serwera. Zanotuj nową tabelę (AspNet_SqlCacheTablesForChangeNotification), nowe procedury składowane oraz wyzwalacze na tabelach Products, 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 za pomocą Web.config określania baz danych do użycia i częstotliwości sondowania w milisekundach. Poniższy znacznik odpytuje bazę danych Northwind raz na 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 buforowane dane. Zobaczymy, jak za pomocą SqlCacheDependency klasy programowo skojarzyć zależności pamięci podręcznej SQL z buforowanymi danymi 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 w kroku 3 przy użyciu narzędzia wiersza polecenia — zwraca wartości aspnet_regsql.exe i tableName dla każdego rekordu w changeId. Nieaktualne zależności pamięci podręcznej SQL są wykluczane z pamięci podręcznej.
Ustawienie pollTime wprowadza kompromis między wydajnością a nieaktualnością danych. Niewielka pollTime 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, uproszczonej tabeli. Jednak poeksperymentuj 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 / Notatka
Powyższy przykład zawiera pojedynczą pollTime wartość w elemecie <sqlCacheDependency> , ale opcjonalnie można określić pollTime wartość w elemecie <add> . Jest to przydatne, jeśli określono wiele baz danych i chcesz dostosować częstotliwość sondowania dla bazy 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żna teraz dodawać elementy do pamięci podręcznej danych ze skojarzoną zależnością 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 zapoznał się z możliwościami 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ć deklaratywnie używanie zależności pamięci podręcznej SQL, otwórz SqlCacheDependencies.aspx stronę w Caching folderze i przeciągnij element GridView z Paska narzędzi na powierzchnię projektową. Ustaw właściwość ID kontrolki GridView na wartość ProductsDeclarative, a następnie z jej inteligentnego tagu wybierz opcję powiązania z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceDeclarative.
Rysunek 5. Tworzenie nowego obiektuDataSource o nazwie ProductsDataSourceDeclarative (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Skonfiguruj obiekt ObjectDataSource do używania ProductsBLL klasy i ustaw listę rozwijaną na karcie SELECT na wartość GetProducts(). Na karcie UPDATE wybierz przeciążenie z trzema UpdateProduct parametrami wejściowymi — productName, unitPricei productID. Ustaw listy rozwijane na wartość (Brak) na kartach INSERT i DELETE.
Rysunek 6. Używanie przeciążenia UpdateProduct z trzema parametrami wejściowymi (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Rysunek 7. Ustaw listę Drop-Down na (Brak) dla kart INSERT i DELETE (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po ukończeniu pracy kreatora konfiguracji źródła danych program Visual Studio utworzy pola związane i pola typu CheckBox w GridView dla każdego pola w źródle danych. Usuń wszystkie pola z wyjątkiem ProductName, CategoryName, i UnitPrice i sformatuj te pola według własnego uznania. W tagu inteligentnym GridView zaznacz pola wyboru Włącz stronicowanie, Włącz sortowanie i Włącz edytowanie. Program Visual Studio ustawi właściwość OldValuesParameterFormatString ObjectDataSource na original_{0}. Aby funkcja edycji kontrolki 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ę web etykiety nad kontrolką GridView i ustaw jej ID właściwość na ODSEvents i jej EnableViewState właściwość na false. Po wprowadzeniu tych zmian znaczniki deklaratywne strony powinny wyglądać podobnie do poniższego. Należy pamiętać, że wprowadzono szereg 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 Selecting obiektu ObjectDataSource 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 podczas pobierania danych z obiektu bazowego. Jeśli obiekt ObjectDataSource uzyskuje dostęp do danych z własnej pamięci podręcznej, to zdarzenie nie zostanie wywołane.
Teraz odwiedź tę stronę za pośrednictwem przeglądarki. Ponieważ nie zaimplementowaliśmy jeszcze jakiegokolwiek buforowania, za każdym razem, gdy przeprowadzasz stronicowanie, sortowanie lub edytowanie siatki, strona powinna wyświetlić tekst „Wybranie zdarzenia wyzwolone”, jak pokazano na rysunku 8.
Rysunek 8. Zdarzenie ObjectDataSource jest Selecting wyzwalane za każdym razem, gdy element GridView jest stronicowany, edytowany lub posortowany (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Jak pokazano w samouczku Buforowanie danych za pomocą ObjectDataSource, ustawienie właściwości EnableCaching na wartość true powoduje, że ObjectDataSource będzie buforować swoje dane przez czas określony przez jego właściwość CacheDuration. Obiekt ObjectDataSource ma również właściwość SqlCacheDependency, która dodaje jedną lub więcej zależności 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 względem tabeli Northwind s Products , ustaw właściwość ObjectDataSource EnableCaching na true i jej SqlCacheDependency właściwość na NorthwindDB:Products.
Uwaga / Notatka
Można użyć zależności pamięci podręcznej SQL oraz wygaśnięcia zależnego od czasu, ustawiając EnableCaching na true, CacheDuration na interwał czasu oraz SqlCacheDependency na nazwę bazy danych i nazw(y) tabel. Źródło ObjectDataSource usunie dane po osiągnięciu określonego czasu wygaśnięcia lub gdy system odpytywania odnotuje, że dane w bazie danych uległy zmianie, w zależności od tego, co nastąpi wcześniej.
Kontrolka GridView w SqlCacheDependencies.aspx wyświetla dane z dwóch tabel — Products i Categories (pole produktu CategoryName jest pobierane przez zapytanie na JOIN). W związku z tym chcemy określić dwie zależności pamięci podręcznej SQL: NorthwindDB:Products; NorthwindDB:Categories .
Rysunek 9: Konfiguracja ObjectDataSource do obsługi buforowania za pomocą zależności pamięci podręcznej SQL w Products oraz Categories (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Po skonfigurowaniu obiektu ObjectDataSource w celu obsługi buforowania ponownie przejdź do strony za pośrednictwem przeglądarki. Ponownie, tekst "Zdarzenie wybierania zostało wyzwolone" powinien pojawić się podczas pierwszej wizyty na stronie, ale powinien zniknąć podczas stronicowania, sortowania lub klikania przycisków Edytuj lub Anuluj. Dzieje się tak dlatego, że po załadowaniu danych do pamięci podręcznej obiektu ObjectDataSource pozostają tam, dopóki nie nastąpi modyfikacja tabel Products lub Categories albo aktualizacja danych za pośrednictwem funkcji GridView.
Po przewijaniu siatki stronami i zauważeniu braku tekstu "Wybrano zdarzenie wyzwolone", 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 pierwszym oknie przeglądarki wyświetl inną stronę danych, posortuj siatkę lub kliknij przycisk Edytuj wiersz. Tym razem ponownie powinno zostać wyświetlone zdarzenie wyboru, ponieważ bazowe dane bazy danych zostały zmodyfikowane (patrz Rysunek 10). Jeśli tekst nie zostanie wyświetlony, zaczekaj 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 aktualizacją danych bazowych a eksmitowaniem buforowanych danych.
Rysunek 10: Modyfikowanie tabeli produktów usuwa buforowane dane produktów (Kliknij, aby zobaczyć obraz w pełnym rozmiarze)
Krok 6: Programowe korzystanie z klasąSqlCacheDependency
W samouczku Buforowanie danych w architekturze przedstawiono korzyści wynikające z używania oddzielnej warstwy buforowania w architekturze, w przeciwieństwie do ścisłego sprzężenia buforowania z obiektem ObjectDataSource. W tym samouczku utworzyliśmy klasę ProductsCL , aby zademonstrować programową pracę 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 s to odpowiednio nazwy bazy danych i tabel. Podobnie jak we właściwości SqlCacheDependency ObjectDataSource, używana nazwa bazy danych jest taka sama jak wartość określona w atrybucie name elementu <add> w Web.config. Nazwa tabeli jest rzeczywistą nazwą tabeli bazy danych.
Aby skojarzyć element SqlCacheDependency 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 czas nieokreślony, ale powiązuje ją z SqlCacheDependency, który znajduje się na tabeli Products. Krótko mówiąc, wartość pozostanie w pamięci podręcznej, dopóki nie zostanie usunięta z powodu ograniczeń pamięci lub ponieważ system sondowania wykrył, że Products tabela uległa zmianie od czasu jej 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 buforującej ProductsCL obecnie przechowuje dane z tabeli Products, wykorzystując mechanizm wygaśnięcia czasowego z limitem 60 sekund. Zaktualizujmy tę klasę, aby używała zależności cache SQL. Metoda ProductsCL klasy s AddCacheItem , która jest odpowiedzialna za dodawanie danych do pamięci podręcznej, zawiera obecnie 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 kontrolkę GridView do strony pod istniejącą kontrolką GridView ProductsDeclarative. Ustaw ten nowy GridView na IDProductsProgrammatic i, za pomocą inteligentnego znaczniku, powiąż go z nowym ObjectDataSource o nazwie ProductsDataSourceProgrammatic. Skonfiguruj obiekt ObjectDataSource do używania 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 o pełnym rozmiarze)
Rysunek 12: Wybierz metodę GetProducts z karty SELECT listy Drop-Down (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 13: Wybierz funkcję UpdateProduct z listy karty UPDATE Drop-Down (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po ukończeniu pracy kreatora konfiguracji źródła danych program Visual Studio utworzy pola związane i pola typu CheckBox w GridView dla każdego pola w źródle danych. Podobnie jak w przypadku pierwszego elementu GridView dodanego do tej strony, usuń wszystkie pola, ale ProductName, CategoryNamei 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. Podobnie jak w przypadku ProductsDataSourceDeclarative ObjectDataSource, program Visual Studio ustawi właściwość ProductsDataSourceProgrammatic ObjectDataSource OldValuesParameterFormatString na wartość original_{0}. Aby funkcja edycji kontrolki 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 klasie ProductCL metodzie AddCacheItem, a następnie rozpocznij debugowanie. Podczas pierwszej wizyty SqlCacheDependencies.aspx punkt przerwania powinien zostać aktywowany, ponieważ dane są żądane po raz pierwszy i umieszczone w pamięci podręcznej. Następnie przejdź do innej strony w widoku tabeli GridView lub posortuj jedną z kolumn. Powoduje to ponowne odpytywanie danych przez GridView, ale dane powinny znajdować się w pamięci podręcznej, ponieważ tabela bazy danych Products nie została zmodyfikowana. Jeśli dane wielokrotnie nie znajdują się w pamięci podręcznej, upewnij się, że na komputerze jest wystarczająca ilość pamięci i spróbuj ponownie.
Przeglądając kilka stron w widoku 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: punkt przerwania zostanie aktywny, wskazując, że buforowane dane zostały usunięte z powodu zmiany w bazie danych; lub punkt przerwania nie zostanie aktywny, co oznacza, że SqlCacheDependencies.aspx teraz wyświetlane są nieaktualne dane. Jeśli punkt kontrolny nie zostanie aktywowany, prawdopodobnie usługa sondowania nie została jeszcze wyzwolona od momentu zmiany danych. Pamiętaj, że usługa sondowania sprawdza zmiany Products w tabeli co pollTime milisekundy, dlatego występuje opóźnienie między aktualizacją danych bazowych a eksmitowaniem buforowanych danych.
Uwaga / Notatka
To opóźnienie najprawdopodobniej wystąpi podczas edytowania jednego z produktów używając kontrolki GridView w SqlCacheDependencies.aspx. W poradniku Buforowanie Danych w Architekturze dodaliśmy MasterCacheKeyArray zależność pamięci podręcznej, aby upewnić się, że dane edytowane za pomocą metody klasy ProductsCLUpdateProduct zostały usunięte z pamięci podręcznej. Jednak zastąpiliśmy tę zależność pamięci podręcznej podczas modyfikowania AddCacheItem metody wcześniej w tym kroku i dlatego ProductsCL klasa będzie nadal pokazywać buforowane dane, dopóki system sondowania nie zanotuje zmiany w Products tabeli. Zobaczymy, jak ponownie wprowadzić zależność pamięci podręcznej MasterCacheKeyArray w kroku 7.
Krok 7. Kojarzenie wielu zależności z buforowanym elementem
Pamiętaj, że MasterCacheKeyArray zależność pamięci podręcznej jest używana 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 metoda GetProductsByCategoryID(categoryID) przechowuje w pamięci podręcznej wystąpienia ProductsDataTables dla każdej wartości categoryID. Jeśli jeden z tych obiektów zostanie wykluczony, MasterCacheKeyArray zależność pamięci podręcznej gwarantuje również, że pozostałe zostaną również usunięte. 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 należy zachować MasterCacheKeyArray zależność pamięci podręcznej 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 zapisane w pamięci podręcznej w ProductsCL klasie zawiera nazwy kategorii i dostawców dla każdego produktu, ale metoda AddCacheItem używa tylko zależności od Products klasy. W takiej sytuacji, jeśli użytkownik zaktualizuje 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 były zależne nie tylko od tabeli Products, ale także od tabel Categories i Suppliers.
KlasaAggregateCacheDependency zapewnia metodę kojarzenia wielu zależności z elementem pamięci podręcznej. Zacznij od utworzenia instancji AggregateCacheDependency. Następnie dodaj zestaw zależności przy użyciu AggregateCacheDependency metody s Add . Podczas wstawiania elementu do pamięci podręcznej danych, przekaż wystąpienie AggregateCacheDependency. Kiedy którakolwiek z zależności wystąpienia zmieni się, buforowany element zostanie usunięty.
Poniżej przedstawiono zaktualizowany kod dla ProductsCL metody klasy s AddCacheItem . Metoda tworzy zależność pamięci podręcznej MasterCacheKeyArray wraz z obiektami SqlCacheDependency dla tabel Products, 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 Productstabelach , Categorieslub Suppliers powodują eksmitowanie buforowanych danych. Ponadto metoda ProductsCL klasy UpdateProduct, która jest wywoływana podczas edytowania produktu za pośrednictwem kontrolki GridView, usuwa zależność pamięci podręcznej MasterCacheKeyArray, co powoduje usunięcie buforowanej zawartości i ponowne pobranie danych przy następnym żądaniu.
Uwaga / Notatka
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 danych wyjściowych ASP.NET z programem SQL Server.
Podsumowanie
Kiedy buforujemy dane z bazy danych, idealnie pozostaną one w pamięci podręcznej, dopóki nie zostaną zmodyfikowane w bazie danych. W przypadku ASP.NET 2.0 można tworzyć zależności pamięci podręcznej SQL i używać ich zarówno w scenariuszach deklaratywnych, jak i programowych. Jednym z wyzwań związanych z tym podejściem jest odkrycie, kiedy dane zostały zmodyfikowane. Pełne wersje programu Microsoft SQL Server 2005 zapewniają możliwości powiadomień, które mogą wysyłać alerty do aplikacji po zmianie wyniku zapytania. W przypadku wersji Express Server 2005 i starszych wersji programu SQL Server należy zamiast tego użyć systemu sondowania. Na szczęście skonfigurowanie niezbędnej infrastruktury sondowania jest dość proste.
Szczęśliwe programowanie!
Dalsza lektura
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Używanie powiadomień zapytania w programie Microsoft SQL Server 2005
- Tworzenie powiadomienia zapytania
-
Buforowanie w ASP.NET za pomocą klasy
SqlCacheDependency -
ASP.NET narzędzie rejestracji programu 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 go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Główni recenzenci tego samouczka byli Marko Rangel, Teresa Murphy i Hilton Giesenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.