Udostępnij za pośrednictwem


Używanie zależności pamięci podręcznej SQL (VB)

Autor: Scott Mitchell

Pobierz plik PDF

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 utrzymują skojarzenia ze źródłowym źródłem danych, co powoduje, że nieaktualne dane przechowywane są zbyt długo lub aktualne dane, które wygasły zbyt szybko. Lepszym rozwiązaniem jest użycie klasy SqlCacheDependency tak, aby dane były buforowane do momentu modyfikacji 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 w celu eksmisji danych z pamięci podręcznej po określonym przedziale czasu. Takie podejście jest najprostszym sposobem zrównoważenia wzrostu wydajności buforowania w przypadku nieaktualności danych. Wybierając czas wygaśnięcia x sekund, deweloper strony przyznaje, aby cieszyć się korzyściami z wydajności buforowania tylko x sekund, ale może odpocząć łatwo, że jej dane nigdy nie będą przestarzałe niż maksymalnie x sekund. Oczywiście w przypadku danych statycznych x można rozszerzyć na okres istnienia aplikacji internetowej, jak znaleziono w samouczku Buforowanie danych podczas uruchamiania aplikacji .

W przypadku buforowania danych bazy danych wygaśnięcie oparte na czasie jest często wybierane pod kątem łatwości użycia, ale często jest nieodpowiednim rozwiązaniem. W idealnym przypadku dane bazy danych pozostaną buforowane do momentu modyfikacji danych bazowych w bazie danych; tylko wtedy pamięć podręczna zostanie eksmitowana. 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ć 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 wdrożenie tego systemu.

ASP.NET 2.0 zapewnia 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 zbadamy, jak używać SqlCacheDependency klasy w scenariuszach deklaratywnych i programowych.

Opis powiadomień i sondowania

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 tym, kiedy ostatnio zaktualizowano określone tabele. Środowisko uruchomieniowe ASP.NET okresowo sonduje bazę danych, aby sprawdzić, jakie 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 eksmitowane.

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. 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 powiadomień SQL Server 2005.

W przypadku sondowania baza danych musi być skonfigurowana tak, aby zawierała tabelę o nazwie AspNet_SqlCacheTablesForChangeNotification z trzema kolumnami — 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 od 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 AspNet_SqlCacheTablesForChangeNotification tabeli baza danych musi również uwzględniać wyzwalacze dla każdej z tabel, które mogą pojawić się w zależności od 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 elemecie AspNet_SqlCacheTablesForChangeNotification.

Środowisko uruchomieniowe ASP.NET śledzi bieżącą wartość changeId tabeli podczas buforowania danych przy użyciu SqlCacheDependency obiektu. Baza danych jest okresowo sprawdzana, a wszystkie SqlCacheDependency obiekty, których changeId wartość w bazie danych różni się od wartości, 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 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 utworzyć za pomocą programu aspnet_regsql.exewiersza 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 microsoft SQL Server o nazwie na serwerze bazy danych o nazwie pubsScottsServer 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 przy użyciu przełącznika -t i zamiast używać przełącznika -ed , -etw 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 bazie danych w pubs usłudze 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 Productstabel , Categoriesi Suppliers . Przyjrzymy się określonej 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 masz jedną z pełnych wersji SQL Server 2005 zainstalowanych na komputerze, prawdopodobnie masz już zainstalowane SQL Server Management Studio na komputerze. Jeśli masz tylko wersję Express, możesz pobrać bezpłatną aplikację Microsoft SQL Server Management Studio.

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.

Dołączanie do hosta lokalnego\SQLExpress Server

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ń itd. 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.

Dołącz element NORTHWND. Baza danych MDF z folderu App_Data

Rysunek 2. Dołączanie NORTHWND.MDF bazy danych z App_Data folderu (kliknij, aby wyświetlić obraz pełnowymiarowy)

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

Zmienianie nazwy dołączonej bazy danych na bardziej Human-Friendly

Rysunek 3. Zmiana nazwy dołączonej bazy danych na bardziej Human-Friendly nazwa

Krok 3. Dodawanie infrastruktury sondowania do bazy danych Northwind

Teraz, gdy dołączyliśmy NORTHWND.MDF bazę danych z App_Data folderu, możemy dodać infrastrukturę 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 pośrednictwem Eksploratora serwera. Zanotuj nową tabelę (AspNet_SqlCacheTablesForChangeNotification), nowe procedury składowane i wyzwalacze w Productstabelach , Categoriesi Suppliers .

Baza danych zawiera teraz niezbędną infrastrukturę sondowania

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 odbywa się przez Web.config określenie baz danych do użycia i częstotliwość sondowania w milisekundach. Poniższe znaczniki sonduje 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 <add> elemecie ( 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ływać się do nazwy bazy danych zdefiniowanej tutaj, a także tabeli, na podstawie których są buforowane dane. Zobaczymy, jak za pomocą SqlCacheDependency klasy programowo skojarzyć zależności pamięci podręcznej SQL z zapisanymi w pamięci podręcznej 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 z powrotem w kroku 3 przy użyciu narzędzia wiersza polecenia — zwraca tableName wartości i changeId dla każdego rekordu aspnet_regsql.exe w AspNet_SqlCacheTablesForChangeNotificationprogramie . 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. Mała 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 usunięciem 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 IDProductsDeclarative i z jego tagu inteligentnego wybierz powiązanie go z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceDeclarative.

Tworzenie nowego obiektuDataSource 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, unitPricei productID. Ustaw listy rozwijane na wartość (Brak) na kartach INSERT i DELETE.

Używanie przeciążenia UpdateProduct z trzema parametrami wejściowymi

Rysunek 6. Użycie przeciążenia UpdateProduct z trzema parametrami wejściowymi (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ustaw listę Drop-Down na (Brak) dla kart INSERT i DELETE

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, CategoryNamei UnitPricei 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 OldValuesParameterFormatStringoriginal_{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 Sub ProductsDataSourceDeclarative_Selecting _
    (sender As Object, e As ObjectDataSourceSelectingEventArgs) _
    Handles ProductsDataSourceDeclarative.Selecting
    ODSEvents.Text = "-- Selecting event fired"
End Sub

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.

Funkcja ObjectDataSource wybierająca zdarzenie jest uruchamiana za każdym razem, gdy element GridView jest stronicowany, edytowany lub posortowany

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.configa 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ść EnableCachingTruena , 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 .

Konfigurowanie obiektu ObjectDataSource do obsługi buforowania przy użyciu zależności pamięci podręcznej SQL w produktach i kategoriach

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.

Modyfikowanie tabeli products eksmituje buforowane dane produktu

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:

Dim productsTableDependency As _
    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ą SqlCacheDependencyProducts . 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.

Dim productsTableDependency As _
    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 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

Zaktualizuj ten kod, aby użyć SqlCacheDependency obiektu zamiast zależności pamięci podręcznej MasterCacheKeyArray :

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

Aby przetestować tę funkcję, dodaj element GridView do strony poniżej istniejącej ProductsDeclarative kontrolki GridView. Ustaw ten nowy element GridView na IDProductsProgrammatic 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.

Konfigurowanie obiektu ObjectDataSource do używania klasy ProductsCL

Rysunek 11. Konfigurowanie obiektu ObjectDataSource do używania ProductsCL klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)

Wybierz metodę GetProducts z listy Drop-Down SELECT Tab

Rysunek 12. Wybierz metodę GetProducts z listy Drop-Down SELECT Tab (Kliknij, aby wyświetlić obraz pełnowymiarowy)

Wybierz metodę UpdateProduct z listy Drop-Down kart UPDATE

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, CategoryNamei UnitPricesformatuj 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.aspxpunkt 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 aktualizacją danych bazowych a eksmitowaniem danych buforowanych.

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 zostały UpdateProduct wykluczone 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 GetProductsByCategoryID(categoryID) metoda buforuje ProductsDataTables wystąpienia dla każdej unikatowej wartości categoryID . Jeśli jeden z tych obiektów zostanie wykluczony, MasterCacheKeyArray zależność pamięci podręcznej gwarantuje, ż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 ważne jest, aby 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 buforowany w ProductsCL klasie zawiera kategorię i nazwy dostawców dla każdego produktu, ale AddCacheItem metoda używa tylko zależności od Productsklasy . 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 zależały nie tylko Products od tabeli, ale także w Categories tabelach 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ż w wystąpieniu AggregateCacheDependency . Gdy dowolnaAggregateCacheDependency z zależności wystąpienia ulegnie zmianie, buforowany element zostanie wykluczony.

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 Productstabel , Categoriesi Suppliers . Wszystkie te elementy są łączone w jeden AggregateCacheDependency obiekt o nazwie aggregateDependencies, który jest następnie przekazywany 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

Przetestuj ten nowy kod. Teraz zmiany w Productstabelach , Categorieslub Suppliers powodują eksmitowanie buforowanych danych. Co więcej, ProductsCL metoda klasy s UpdateProduct , która jest wywoływana podczas edytowania produktu za pośrednictwem gridview, eksmituje MasterCacheKeyArray zależność pamięci podręcznej, co powoduje eksmitowanie buforowanej ProductsDataTable pamięci podręcznej, a dane mają zostać ponownie pobrane 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: Using ASP.NET Output Caching with SQL Server (Używanie buforowania danych wyjściowych ASP.NET z SQL Server).

Podsumowanie

Podczas buforowania danych bazy danych dane w idealnym przypadku pozostaną w pamięci podręcznej, dopóki nie zostaną zmodyfikowane w bazie danych. Dzięki 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 platformy 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 zamiast tego 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:

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 przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Marko Rangel, Teresa Murphy i Hilton Giesenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .