Udostępnij za pomocą


Buforowanie danych w architekturze (VB)

Autor : Scott Mitchell

Pobierz plik PDF

W poprzednim samouczku dowiedzieliśmy się, jak zastosować buforowanie w warstwie prezentacji. Z tego samouczka dowiesz się, jak korzystać z naszej architektury warstwowej w celu buforowania danych w warstwie logiki biznesowej. W tym celu rozszerzymy architekturę tak, aby zawierała warstwę buforowania.

Wprowadzenie

Jak pokazano w poprzednim samouczku, buforowanie danych ObjectDataSource jest tak proste, jak ustawienie kilku właściwości. Niestety obiekt ObjectDataSource stosuje buforowanie w warstwie prezentacji, która ściśle łączy zasady buforowania ze stroną ASP.NET. Jedną z przyczyn tworzenia architektury warstwowej jest umożliwienie zerwania takich sprzężeń. Warstwa logiki biznesowej, na przykład, rozdziela logikę biznesową ze stron ASP.NET, podczas gdy warstwa dostępu do danych rozdziela szczegóły dostępu do danych. To oddzielenie logiki biznesowej i szczegółów dostępu do danych jest preferowane, między innymi dlatego, że system staje się bardziej czytelny, łatwiejszy w utrzymaniu i bardziej elastyczny w przypadku zmian. Pozwala to również na wiedzę o domenie i podział pracy deweloper pracujący nad warstwą prezentacji nie musi być zaznajomiony ze szczegółami bazy danych, aby wykonać swoją pracę. Oddzielenie zasad buforowania z warstwy prezentacji oferuje podobne korzyści.

W tym samouczku rozszerzymy naszą architekturę tak, aby zawierała warstwę buforowania (lub cl w skrócie), która wykorzystuje nasze zasady buforowania. Warstwa buforowania będzie zawierać klasę ProductsCL, która zapewnia dostęp do informacji o produkcie za pomocą takich metod jak GetProducts(), GetProductsByCategoryID(categoryID) i inne, które po wywołaniu najpierw spróbują pobrać dane z pamięci podręcznej. Jeśli pamięć podręczna jest pusta, te metody wywołają odpowiednią ProductsBLL metodę w warstwie BLL, co z kolei spowoduje pobranie danych z DAL. Metody ProductsCL buforuje dane pobrane z usługi BLL przed ich zwróceniem.

Jak pokazano na rysunku 1, cl znajduje się między warstwami prezentacji i logiki biznesowej.

Warstwa buforowania (CL) to kolejna warstwa w naszej architekturze

Rysunek 1. Warstwa buforowania (CL) to kolejna warstwa w naszej architekturze

Krok 1. Tworzenie klas warstw buforowania

W tym samouczku utworzymy bardzo prostą cl z pojedynczą klasą ProductsCL , która ma tylko kilka metod. Utworzenie pełnej warstwy buforowania dla całej aplikacji wymagałoby utworzenia klas CategoriesCL, EmployeesCL i SuppliersCL oraz zapewnienia metod w tych klasach warstwy buforowania dla każdej metody dostępu do danych lub modyfikacji w warstwie logiki biznesowej (BLL). Podobnie jak w przypadku bibliotek BLL i DAL, warstwa buforowania najlepiej byłaby zaimplementowana jako osobny projekt biblioteka klas; jednak zaimplementujemy ją jako klasę w folderze App_Code.

Aby dokładniej oddzielić klasy CL od klas DAL i BLL, utwórzmy nowy podfolder w folderze App_Code . Kliknij prawym przyciskiem myszy App_Code folder w Eksploratorze rozwiązań, wybierz pozycję Nowy folder i nazwij nowy folder CL. Po utworzeniu tego folderu dodaj do niego nową klasę o nazwie ProductsCL.vb.

Dodawanie nowego folderu o nazwie CL i klasy o nazwie ProductsCL.vb

Rysunek 2. Dodawanie nowego folderu o nazwie CL i klasy o nazwie ProductsCL.vb

Klasa ProductsCL powinna zawierać ten sam zestaw metod dostępu do danych i modyfikacji, co w odpowiedniej klasie warstwy logiki biznesowej (ProductsBLL). Zamiast tworzyć wszystkie te metody, po prostu skompilujmy kilka tutaj, aby poczuć wzorce używane przez CL. W szczególności dodamy metody GetProducts() i GetProductsByCategoryID(categoryID) w kroku 3 oraz przeciążenie UpdateProduct w kroku 4. Pozostałe metody ProductsCL oraz klasy CategoriesCL, EmployeesCL i SuppliersCL można dodawać w wolnym czasie.

Krok 2. Odczytywanie i zapisywanie w pamięci podręcznej danych

Funkcja buforowania ObjectDataSource eksplorowana w poprzednim samouczku wewnętrznie używa pamięci podręcznej danych ASP.NET do przechowywania danych pobranych z biblioteki BLL. Dostęp do pamięci podręcznej danych można również uzyskać programowo z klas kodu zaplecza stron ASP.NET lub z klas w architekturze aplikacji internetowej. Aby odczytywać i zapisywać dane w pamięci podręcznej klasy code-behind strony ASP.NET, użyj następującego wzorca:

' Read from the cache
Dim value as Object = Cache("key")
' Add a new item to the cache
Cache("key") = value
Cache.Insert(key, value)
Cache.Insert(key, value, CacheDependency)
Cache.Insert(key, value, CacheDependency, DateTime, TimeSpan)

Metoda Cache klasy Insert ma wiele przeciążeń. Cache("key") = value i Cache.Insert(key, value) są synonimami, a oba dodają element do pamięci podręcznej przy użyciu określonego klucza bez zdefiniowanego wygaśnięcia. Zazwyczaj chcemy określić wygaśnięcie przy dodawaniu elementu do pamięci podręcznej, albo jako zależność, albo jako wygaśnięcie zależne od czasu, albo oba jednocześnie. Użyj jednego z innych Insert przeciążeń metody, aby zapewnić zależności lub informacje o wygaśnięciu na podstawie czasu.

Metody warstwy buforowania muszą najpierw sprawdzić, czy żądane dane znajdują się w pamięci podręcznej, a jeśli tak, to je stamtąd zwrócić. Jeśli żądane dane nie są w pamięci podręcznej, należy wywołać odpowiednią metodę BLL. Jego wartość zwracana powinna być buforowana, a następnie zwracana, jak pokazano na poniższym diagramie sekwencji.

Metody warstwy buforowania zwracają dane z pamięci podręcznej, jeśli są dostępne

Rysunek 3. Metody warstwy buforowania zwracają dane z pamięci podręcznej, jeśli są dostępne

Sekwencja przedstawiona na rysunku 3 jest realizowana w klasach CL przy użyciu następującego wzorca:

Dim instance As Type = TryCast(Cache("key"), Type)
If instance Is Nothing Then
    instance = BllMethodToGetInstance()
    Cache.Insert(key, instance, ...)
End If
Return instance

Tutaj typ to typ danych przechowywanych w pamięci podręcznej Northwind.ProductsDataTable, na przykład klucz jest kluczem, który jednoznacznie identyfikuje element pamięci podręcznej. Jeśli element o określonym kluczu nie znajduje się w pamięci podręcznej, wystąpienie będzie Nothing i dane zostaną pobrane z odpowiedniej metody BLL i dodane do pamięci podręcznej. Po osiągnięciu punktu Return instance, instancja zawiera odwołanie do danych, pochodzące z pamięci podręcznej lub pobrane z usługi BLL.

Pamiętaj, aby użyć powyższego wzorca podczas uzyskiwania dostępu do danych z pamięci podręcznej. Poniższy wzorzec, który na pierwszy rzut oka wygląda równoważnie, zawiera subtelną różnicę, która wprowadza warunek wyścigu. Warunki wyścigu są trudne do debugowania, ponieważ ujawniają się sporadycznie i są trudne do odtworzenia.

If Cache("key") Is Nothing Then
    Cache.Insert(key, BllMethodToGetInstance(), ...)
End If
Return Cache("key")

Różnica w tym drugim, niepoprawnym fragmencie kodu polega na tym, że zamiast przechowywać odwołanie do buforowanego elementu w zmiennej lokalnej, dostęp do pamięci podręcznej danych jest uzyskiwany bezpośrednio w instrukcji warunkowej i w elemencie Return. Załóżmy, że gdy ten kod zostanie osiągnięty, Cache("key") nie jest Nothing, ale zanim zostanie osiągnięta instrukcja Return, system eksmituje klucz z pamięci podręcznej. W tym rzadkim przypadku kod zwróci Nothing , a nie obiekt oczekiwanego typu.

Uwaga / Notatka

Pamięć podręczna danych jest bezpieczna dla wątków, więc nie trzeba synchronizować dostępu wątku do prostych odczytów lub zapisów. Jeśli jednak musisz wykonać wiele operacji na danych w pamięci podręcznej, które muszą być atomowe, odpowiadasz za zaimplementowanie blokady lub innego mechanizmu w celu zapewnienia bezpieczeństwa współbieżności. Aby uzyskać więcej informacji, zobacz Synchronizowanie dostępu do pamięci podręcznej ASP.NET.

Element można eksmitować programowo z pamięci podręcznej danych przy użyciu Remove metody w następujący sposób:

Cache.Remove(key)

Krok 3: Zwracanie informacji o produkcieProductsCLz klasy

Na potrzeby tego samouczka zaimplementujmy dwie metody zwracania informacji o produkcie ProductsCL z klasy: GetProducts() i GetProductsByCategoryID(categoryID). Podobnie jak w przypadku ProductsBL klasy w warstwie logiki biznesowej metoda GetProducts() w cl zwraca informacje o wszystkich produktach jako Northwind.ProductsDataTable obiekcie, a jednocześnie GetProductsByCategoryID(categoryID) zwraca wszystkie produkty z określonej kategorii.

Poniższy kod przedstawia część metod w ProductsCL klasie:

<System.ComponentModel.DataObject()> _
Public Class ProductsCL
    Private _productsAPI As ProductsBLL = Nothing
    Protected ReadOnly Property API() As ProductsBLL
        Get
            If _productsAPI Is Nothing Then
                _productsAPI = New ProductsBLL()
            End If
            Return _productsAPI
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
    (DataObjectMethodType.Select, True)> _
    Public Function GetProducts() As Northwind.ProductsDataTable
        Const rawKey As String = "Products"
        ' See if the item is in the cache
        Dim products As Northwind.ProductsDataTable = _
            TryCast(GetCacheItem(rawKey), Northwind.ProductsDataTable)
        If products Is Nothing Then
            ' Item not found in cache - retrieve it and insert it into the cache
            products = API.GetProducts()
            AddCacheItem(rawKey, products)
        End If
        Return products
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (DataObjectMethodType.Select, False)> _
    Public Function GetProductsByCategoryID(ByVal categoryID As Integer) _
        As Northwind.ProductsDataTable
        If (categoryID < 0) Then
            Return GetProducts()
        Else
            Dim rawKey As String = String.Concat("ProductsByCategory-", categoryID)
            ' See if the item is in the cache
            Dim products As Northwind.ProductsDataTable = _
                TryCast(GetCacheItem(rawKey), Northwind.ProductsDataTable)
            If products Is Nothing Then
                ' Item not found in cache - retrieve it and insert it into the cache
                products = API.GetProductsByCategoryID(categoryID)
                AddCacheItem(rawKey, products)
            End If
            Return products
        End If
    End Function
End Class

Najpierw zwróć uwagę na atrybuty DataObject i DataObjectMethodAttribute oraz ich zastosowanie w klasie i metodach. Te atrybuty dostarczają informacji do kreatora ObjectDataSource, określając, jakie klasy i metody powinny być uwzględnione w krokach kreatora. Ponieważ klasy i metody CL będą dostępne z obiektu ObjectDataSource w warstwie prezentacji, dodałem te atrybuty, aby ulepszyć środowisko projektowania w czasie projektowania. Zapoznaj się z samouczkiem Tworzenie warstwy logiki biznesowej , aby uzyskać bardziej szczegółowy opis tych atrybutów i ich wpływu.

W metodach GetProducts() i GetProductsByCategoryID(categoryID), dane zwrócone z metody GetCacheItem(key) są przypisane do zmiennej lokalnej. Metoda GetCacheItem(key) , którą wkrótce zbadamy, zwraca określony element z pamięci podręcznej na podstawie określonego klucza. Jeśli takie dane nie zostaną znalezione w pamięci podręcznej, zostaną pobrane z odpowiedniej ProductsBLL metody klasy, a następnie dodane do pamięci podręcznej przy użyciu AddCacheItem(key, value) metody .

Metody GetCacheItem(key) i AddCacheItem(key, value) interfejsują z pamięcią podręczną danych, odpowiednio odczytując i zapisując wartości. Metoda GetCacheItem(key) jest prostsza z tych dwóch. Po prostu zwraca wartość z klasy Cache przy użyciu przekazanego klucza:

Private Function GetCacheItem(ByVal rawKey As String) As Object
    Return HttpRuntime.Cache(GetCacheKey(rawKey))
End Function
Private ReadOnly MasterCacheKeyArray() As String = {"ProductsCache"}
Private Function GetCacheKey(ByVal cacheKey As String) As String
    Return String.Concat(MasterCacheKeyArray(0), "-", cacheKey)
End Function

GetCacheItem(key) nie używa wartości klucza zgodnie z podaną wartością, ale zamiast tego wywołuje metodę GetCacheKey(key) która zwraca klucz z prefiksem ProductsCache-. Element MasterCacheKeyArray, który przechowuje ciąg ProductsCache, jest również używany przez metodę AddCacheItem(key, value) , ponieważ zobaczymy to chwilowo.

Z klasy ASP.NET w kodzie obsługi można uzyskać dostęp do pamięci podręcznej danych za pomocą właściwości klasy Page, co umożliwia składnię, na przykład Cache, zgodnie z opisem w kroku 2. Z klasy w ramach architektury można uzyskać dostęp do pamięci podręcznej danych przy użyciu metody HttpRuntime.Cache lub HttpContext.Current.Cache. Wpis w blogu Petera JohnsonaHttpRuntime.Cache vs. HttpContext.Current.Cache zauważa niewielką przewagę wydajności w użyciu HttpRuntime zamiast HttpContext.Current; w związku z tym ProductsCL używa HttpRuntime.

Uwaga / Notatka

Jeśli Twoja architektura jest zaimplementowana przy użyciu projektów bibliotek klas, musisz dodać odwołanie do zestawu System.Web, aby móc używać klas HttpRuntime i HttpContext.

Jeśli element nie zostanie znaleziony w pamięci podręcznej, ProductsCL metody klasy pobierają dane z biblioteki BLL i dodają je do pamięci podręcznej przy użyciu AddCacheItem(key, value) metody . Aby dodać wartość do pamięci podręcznej, możemy użyć następującego kodu, który wygasa po 60 sekundach.

Const CacheDuration As Double = 60.0
Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
    DataCache.Insert(GetCacheKey(rawKey), value, Nothing, _
        DateTime.Now.AddSeconds(CacheDuration), _
        System.Web.Caching.Cache.NoSlidingExpiration)
End Sub

DateTime.Now.AddSeconds(CacheDuration) określa, że wygasa po 60 sekundach, podczas gdy System.Web.Caching.Cache.NoSlidingExpiration wskazuje, że nie ma przesunięcia terminu wygaśnięcia. Chociaż przeciążenie metody Insert posiada parametry wejściowe zarówno dla wygaśnięcia stałego, jak i przesuwanego, można podać tylko jeden z nich. Jeśli spróbujesz określić zarówno bezwzględny czas, jak i przedział czasu, Insert metoda zgłosi ArgumentException wyjątek.

Uwaga / Notatka

Ta implementacja AddCacheItem(key, value) metody obecnie ma pewne wady. Rozwiążemy te problemy i rozwiążemy je w kroku 4.

Krok 4. Unieważnienie pamięci podręcznej po zmodyfikowaniu danych za pomocą architektury

Oprócz metod pobierania danych warstwa buforowania musi zapewnić takie same metody jak BLL do wstawiania, aktualizowania i usuwania danych. Metody modyfikacji danych CL nie modyfikują buforowanych danych, a zamiast tego wywołują odpowiednią metodę modyfikacji danych BLL, a następnie unieważniają ją. Jak pokazano w poprzednim samouczku, jest to to samo zachowanie, które stosuje ObjectDataSource, gdy jego funkcje buforowania są włączone i gdy jego metody Insert, Update lub Delete są wywoływane.

Następujące UpdateProduct przeciążenie ilustruje sposób implementowania metod modyfikacji danych w CL:

<DataObjectMethodAttribute(DataObjectMethodType.Update, False)> _
Public Function UpdateProduct(productName As String, _
    unitPrice As Nullable(Of Decimal), productID As Integer) _
    As Boolean
    Dim result As Boolean = API.UpdateProduct(productName, unitPrice, productID)
    ' TODO: Invalidate the cache
    Return result
End Function

Wywoływana jest metoda warstwy logiki biznesowej do modyfikacji danych, ale zanim jej odpowiedź zostanie zwrócona, musimy unieważnić cache. Niestety, unieważnienie pamięci podręcznej nie jest proste, ponieważ klasa ProductsCL oraz metody GetProducts() i GetProductsByCategoryID(categoryID) dodają elementy do pamięci podręcznej z różnymi kluczami, a metoda GetProductsByCategoryID(categoryID) dodaje inny element pamięci podręcznej dla każdego unikalnego identyfikatora kategorii.

Podczas unieważniania pamięci podręcznej musimy usunąć wszystkie elementy, które mogły zostać dodane przez klasę ProductsCL . Można to osiągnąć przez skojarzenie zależności pamięci podręcznej z każdym elementem dodanym do pamięci podręcznej w metodzie AddCacheItem(key, value) . Ogólnie rzecz biorąc, zależność pamięci podręcznej może być innym elementem w pamięci podręcznej, plikiem w systemie plików lub danymi z bazy danych programu Microsoft SQL Server. Gdy zależność ulegnie zmianie lub zostanie usunięta z pamięci podręcznej, elementy pamięci podręcznej, z których jest skojarzona, są automatycznie eksmitowane z pamięci podręcznej. W tym samouczku chcemy utworzyć dodatkowy element w pamięci podręcznej, który służy jako zależność pamięci podręcznej dla wszystkich elementów dodanych przez klasę ProductsCL. Dzięki temu wszystkie te elementy można usunąć z pamięci podręcznej, usuwając po prostu zależność pamięci podręcznej.

Zaktualizujmy metodę AddCacheItem(key, value) tak, aby każdy element dodany do pamięci podręcznej za pomocą tej metody był skojarzony z jedną zależnością pamięci podręcznej:

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), _
        System.Web.Caching.Cache.NoSlidingExpiration)
End Sub

MasterCacheKeyArray to tablica ciągów zawierająca pojedynczą wartość ProductsCache. Najpierw element pamięci podręcznej jest dodawany do pamięci podręcznej i przypisany do bieżącej daty i godziny. Jeśli element pamięci podręcznej już istnieje, zostanie zaktualizowany. Następnie zostanie utworzona zależność pamięci podręcznej. Konstruktor CacheDependency klasy ma wiele przeciążeń, ale w tym przypadku oczekuje dwóch String tablic wejściowych. Pierwszy określa zestaw plików, które mają być używane jako zależności. Ponieważ nie chcemy używać żadnych zależności opartych na plikach, wartość Nothing jest używana dla pierwszego parametru wejściowego. Drugi parametr wejściowy określa zestaw kluczy pamięci podręcznej do użycia jako zależności. W tym miejscu określamy naszą pojedynczą zależność. MasterCacheKeyArray Element CacheDependency jest następnie przekazywany do Insert metody .

W tej modyfikacji AddCacheItem(key, value), unieważnienie pamięci podręcznej jest tak proste jak usunięcie zależności.

<DataObjectMethodAttribute(DataObjectMethodType.Update, False)> _
Public Function UpdateProduct(ByVal productName As String, _
    ByVal unitPrice As Nullable(Of Decimal), ByVal productID As Integer) _
    As Boolean
    Dim result As Boolean = API.UpdateProduct(productName, unitPrice, productID)
    ' Invalidate the cache
    InvalidateCache()
    Return result
End Function
Public Sub InvalidateCache()
    ' Remove the cache dependency
    HttpRuntime.Cache.Remove(MasterCacheKeyArray(0))
End Sub

Krok 5. Wywoływanie warstwy buforowania z warstwy prezentacji

Klasy i metody warstwy buforowania mogą służyć do pracy z danymi przy użyciu technik, które omówiliśmy w tych samouczkach. Aby zilustrować pracę z danymi w pamięci podręcznej, zapisz zmiany w ProductsCL klasie, a następnie otwórz FromTheArchitecture.aspx stronę w folderze Caching i dodaj kontrolkę GridView. Na podstawie tagu inteligentnego GridView utwórz nowy obiekt ObjectDataSource. W pierwszym kroku kreatora powinna zostać wyświetlona ProductsCL klasa jako jedna z dostępnych opcji na liście rozwijanej.

Klasa ProductsCL znajduje się na liście obiektów biznesowych Drop-Down

Rysunek 4.ProductsCL Klasa jest uwzględniona na liście obiektów biznesowych Drop-Down (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po wybraniu ProductsCL kliknij przycisk Dalej. Lista rozwijana na karcie SELECT zawiera dwa elementy, GetProducts() i GetProductsByCategoryID(categoryID). Karta UPDATE ma jedno przeciążenie UpdateProduct. Wybierz metodę GetProducts() na karcie SELECT i UpdateProducts metodę na karcie UPDATE, a następnie kliknij przycisk Zakończ.

Metody klasy ProductsCL są wymienione na listach Drop-Down

Rysunek 5. ProductsCL Metody klas są wyświetlane na listach Drop-Down (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po zakończeniu działania kreatora, program Visual Studio ustawi właściwość ObjectDataSource na OldValuesParameterFormatStringoriginal_{0} i doda odpowiednie pola do kontrolki GridView. OldValuesParameterFormatString Zmień właściwość z powrotem na wartość domyślną, {0}i skonfiguruj element GridView, aby obsługiwał stronicowanie, sortowanie i edytowanie. Ponieważ przeciążenie używane przez CL akceptuje tylko edytowaną nazwę i cenę produktu, ogranicz GridView, aby tylko te pola były edytowalne.

W poprzednim samouczku zdefiniowaliśmy element GridView, aby uwzględnić pola dla ProductName, CategoryName i UnitPrice. Możesz zreplikować to formatowanie i strukturę. W takim przypadku znacznik deklaratywny GridView i ObjectDataSource powinien wyglądać podobnie do następującego:

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
    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") %>'></asp:Label>
            </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="ProductsDataSource" 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>

W tym momencie mamy stronę korzystającą z warstwy buforowania. Aby zobaczyć pamięć podręczną w akcji, ustaw punkty przerwania w klasie ProductsCL oraz metodach GetProducts()UpdateProduct. Odwiedź stronę w przeglądarce i przejdź przez kod podczas sortowania i stronicowania, aby zobaczyć dane pobierane z pamięci podręcznej. Następnie zaktualizuj rekord i zwróć uwagę, że pamięć podręczna jest unieważniona, a w związku z tym jest pobierana z usługi BLL, gdy dane są przywracane do kontrolki GridView.

Uwaga / Notatka

Warstwa cache dostarczona w pobraniu wraz z tym artykułem nie jest kompletna. Zawiera tylko jedną klasę , ProductsCLktóra obsługuje tylko kilka metod. Co więcej, tylko jedna strona ASP.NET używa cl (~/Caching/FromTheArchitecture.aspx) wszystkie inne nadal odwołują się bezpośrednio do BLL. Jeśli planujesz użycie CL w swojej aplikacji, wszystkie wywołania z warstwy prezentacji powinny trafiać do CL, co wymagałoby, aby klasy i metody CL objęły te, które są obecnie używane w warstwie prezentacji przez BLL.

Podsumowanie

Buforowanie można stosować w warstwie prezentacji z kontrolkami SqlDataSource i ObjectDataSource ASP.NET 2.0 s, dlatego w idealnym przypadku obowiązki buforowania byłyby delegowane do oddzielnej warstwy w architekturze. W tym samouczku utworzyliśmy warstwę buforowania, która znajduje się między warstwą prezentacji a warstwą logiki biznesowej. Warstwa buforowania musi zapewnić ten sam zestaw klas i metod, które istnieją w warstwie logiki biznesowej (BLL) i są wywoływane przez warstwę prezentacji.

Przykłady warstwy buforowania, które zbadaliśmy w tym i poprzednich samouczkach, wykazały reaktywne ładowanie. W przypadku reaktywnego ładowania dane są ładowane do pamięci podręcznej tylko wtedy, gdy występuje żądanie danych, a dane te nie znajdują się w pamięci podręcznej. Dane mogą być również aktywnie ładowane do pamięci podręcznej— technika, która ładuje dane do pamięci podręcznej, zanim będzie ona rzeczywiście potrzebna. W następnym samouczku zobaczymy przykład proaktywnego ładowania, gdy przyjrzymy się, jak przechowywać wartości statyczne w pamięci podręcznej podczas uruchamiania aplikacji.

Szczęśliwe programowanie!

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łówny recenzent tego samouczka to Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.