Share via


Zwischenspeichern von Daten in der Architektur (VB)

von Scott Mitchell

PDF herunterladen

Im vorherigen Tutorial haben wir gelernt, wie Sie das Zwischenspeichern auf der Präsentationsebene anwenden. In diesem Tutorial erfahren Sie, wie Sie unsere mehrschichtige Architektur nutzen, um Daten auf der Geschäftslogikebene zwischenzuspeichern. Dazu erweitern wir die Architektur um eine Cacheebene.

Einführung

Wie im vorherigen Tutorial gezeigt, ist das Zwischenspeichern der ObjectDataSource-Daten so einfach wie das Festlegen einiger Eigenschaften. Leider wendet ObjectDataSource die Zwischenspeicherung auf der Präsentationsebene an, wodurch die Zwischenspeicherungsrichtlinien eng mit der Seite ASP.NET gekoppelt werden. Einer der Gründe für die Erstellung einer mehrstufigen Architektur besteht darin, dass solche Kopplungen unterbrochen werden können. Die Geschäftslogikebene entkoppelt für instance die Geschäftslogik von den ASP.NET Seiten, während die Datenzugriffsebene die Datenzugriffsdetails entkoppelt. Diese Entkopplung von Geschäftslogik und Datenzugriffsdetails wird bevorzugt, zum Teil, weil sie das System lesbarer, verwaltbarer und flexibler für Änderungen macht. Es ermöglicht auch Domänenwissen und Arbeitsteilung, die ein Entwickler, der auf der Präsentationsebene arbeitet, nicht mit den Details der Datenbank vertraut sein muss, um seine Arbeit zu erledigen. Das Entkoppeln der Zwischenspeicherungsrichtlinie von der Präsentationsebene bietet ähnliche Vorteile.

In diesem Tutorial erweitern wir unsere Architektur, um eine Cacheebene (kurz CL) einzuschließen, die unsere Cacherichtlinie verwendet. Die Cacheebene enthält eine ProductsCL Klasse, die Zugriff auf Produktinformationen mit Methoden wie GetProducts(), GetProductsByCategoryID(categoryID)usw. ermöglicht, die beim Aufrufen zuerst versucht, die Daten aus dem Cache abzurufen. Wenn der Cache leer ist, rufen diese Methoden die entsprechende ProductsBLL Methode in der BLL auf, die wiederum die Daten aus dem DAL abrufen würde. Die ProductsCL Methoden speichern die aus der BLL abgerufenen Daten zwischen, bevor sie zurückgegeben werden.

Wie Abbildung 1 zeigt, befindet sich die CL zwischen der Präsentations- und der Geschäftslogikebene.

Die Cacheebene (CL) ist eine weitere Ebene in unserer Architektur.

Abbildung 1: Die Cacheebene (CL) ist eine weitere Ebene in unserer Architektur

Schritt 1: Erstellen der Zwischenspeicherebenenklassen

In diesem Tutorial erstellen wir eine sehr einfache CL mit einer einzelnen Klasse ProductsCL , die nur über eine Handvoll Methoden verfügt. Das Erstellen einer vollständigen Cacheebene für die gesamte Anwendung erfordert das Erstellen CategoriesCLvon , EmployeesCLund Klassen SuppliersCL sowie die Bereitstellung einer Methode in diesen Caching Layer-Klassen für jede Datenzugriffs- oder Änderungsmethode in der BLL. Wie bei BLL und DAL sollte die Cacheebene idealerweise als separates Klassenbibliotheksprojekt implementiert werden; Wir implementieren sie jedoch als Klasse im App_Code Ordner.

Um die CL-Klassen besser von den DAL- und BLL-Klassen zu trennen, erstellen sie einen neuen Unterordner im App_Code Ordner. Klicken Sie mit der rechten Maustaste auf den App_Code Ordner im Projektmappen-Explorer, wählen Sie Neuer Ordner aus, und nennen Sie den neuen Ordner CL. Nachdem Sie diesen Ordner erstellt haben, fügen Sie ihm eine neue Klasse mit dem Namen ProductsCL.vbhinzu.

Hinzufügen eines neuen Ordners namens CL und einer Klasse namens ProductsCL.vb

Abbildung 2: Hinzufügen eines neuen Ordners namens CL und einer Klasse namens ProductsCL.vb

Die ProductsCL -Klasse sollte denselben Satz von Datenzugriffs- und -änderungsmethoden wie in der entsprechenden Business Logic Layer-Klasse (ProductsBLL) enthalten. Anstatt alle diese Methoden zu erstellen, erstellen wir hier einfach ein paar, um ein Gefühl für die von der CL verwendeten Muster zu erhalten. Insbesondere fügen wir die GetProducts() Methoden und GetProductsByCategoryID(categoryID) in Schritt 3 und eine UpdateProduct Überladung in Schritt 4 hinzu. Sie können die verbleibenden ProductsCL Methoden und CategoriesCL, EmployeesCLund SuppliersCL Klassen nach Belieben hinzufügen.

Schritt 2: Lesen und Schreiben in den Datencache

Die im vorherigen Tutorial untersuchte ObjectDataSource-Zwischenspeicherung verwendet intern den ASP.NET Datencache, um die aus der BLL abgerufenen Daten zu speichern. Auf den Datencache kann auch programmgesteuert über ASP.NET CodeBehind-Klassen oder über die Klassen in der Architektur der Webanwendung zugegriffen werden. Verwenden Sie das folgende Muster, um aus einer CodeBehind-Klasse der ASP.NET Seite in den Datencache zu lesen und in den Datencache zu schreiben:

' 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)

Die Cache Methode s Insert der Klasse verfügt über eine Reihe von Überladungen. Cache("key") = value und Cache.Insert(key, value) sind synonym, und beide fügen dem Cache ein Element mithilfe des angegebenen Schlüssels ohne definierten Ablauf hinzu. In der Regel möchten wir beim Hinzufügen eines Elements zum Cache einen Ablauf angeben, entweder als Abhängigkeit, als zeitbasiertes Ablaufdatum oder beides. Verwenden Sie eine der anderen Insert Methoden-s-Überladungen, um Abhängigkeits- oder zeitbasierte Ablaufinformationen bereitzustellen.

Die Cacheebenen-Methoden müssen zuerst überprüfen, ob sich die angeforderten Daten im Cache befinden, und wenn ja, sie von dort zurückgeben. Wenn sich die angeforderten Daten nicht im Cache befinden, muss die entsprechende BLL-Methode aufgerufen werden. Der Rückgabewert sollte zwischengespeichert und dann zurückgegeben werden, wie im folgenden Sequenzdiagramm dargestellt.

Die Methoden der Zwischenspeicherebene geben Daten aus dem Cache zurück, wenn diese verfügbar sind.

Abbildung 3: Die Methoden der Zwischenspeicherebene geben Daten aus dem Cache zurück, wenn diese verfügbar sind.

Die in Abbildung 3 dargestellte Sequenz wird in den CL-Klassen mit dem folgenden Muster ausgeführt:

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

Hier ist Type der Typ der Daten, die im Cache Northwind.ProductsDataTablegespeichert werden, z. B. während key der Schlüssel ist, der das Cacheelement eindeutig identifiziert. Wenn sich das Element mit dem angegebenen Schlüssel nicht im Cache befindet, wird Nothinginstance, und die Daten werden von der entsprechenden BLL-Methode abgerufen und dem Cache hinzugefügt. Wenn der Zeitpunkt Return instance erreicht ist, enthält instance einen Verweis auf die Daten, entweder aus dem Cache oder aus der BLL abgerufen.

Achten Sie darauf, dass Sie das obige Muster verwenden, wenn Sie auf Daten aus dem Cache zugreifen. Das folgende Muster, das auf den ersten Blick gleichwertig aussieht, enthält einen subtilen Unterschied, der eine Racebedingung einführt. Racebedingungen sind schwierig zu debuggen, da sie sich sporadisch offenbaren und schwer zu reproduzieren sind.

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

Der Unterschied in diesem zweiten, falschen Codeausschnitt besteht darin, dass anstatt einen Verweis auf das zwischengespeicherte Element in einer lokalen Variablen zu speichern, auf den Datencache direkt in der bedingten Anweisung und in der Returnzugegriffen wird. Stellen Sie sich vor, dass, wenn dieser Code erreicht wird, Cache("key") nicht Nothingist, aber bevor die Return -Anweisung erreicht wird, das System den Schlüssel aus dem Cache entfernt. In diesem seltenen Fall gibt der Code anstelle eines Objekts des erwarteten Typs zurück Nothing .

Hinweis

Der Datencache ist threadsicher, sodass Sie den Threadzugriff für einfache Lese- oder Schreibvorgänge nicht synchronisieren müssen. Wenn Sie jedoch mehrere Vorgänge für Daten im Cache ausführen müssen, die atomar sein müssen, sind Sie für die Implementierung einer Sperre oder eines anderen Mechanismus verantwortlich, um die Threadsicherheit zu gewährleisten. Weitere Informationen finden Sie unter Synchronisieren des Zugriffs auf den ASP.NET Cache .

Ein Element kann programmgesteuert aus dem Datencache entfernt werden, indem die Remove -Methode wie folgt verwendet wird:

Cache.Remove(key)

Schritt 3: Zurückgeben von Produktinformationen aus derProductsCLKlasse

In diesem Tutorial werden zwei Methoden zum Zurückgeben von Produktinformationen aus der ProductsCL -Klasse implementiert: GetProducts() und GetProductsByCategoryID(categoryID). Wie bei der ProductsBL -Klasse in der Geschäftslogikebene gibt die GetProducts() -Methode in der CL Informationen zu allen Produkten als Northwind.ProductsDataTable -Objekt zurück, während GetProductsByCategoryID(categoryID) alle Produkte aus einer angegebenen Kategorie zurückgegeben werden.

Der folgende Code zeigt einen Teil der Methoden in der ProductsCL -Klasse:

<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

Notieren Sie sich zunächst die DataObject Attribute und DataObjectMethodAttribute , die auf die Klasse und die Methoden angewendet werden. Diese Attribute stellen Dem ObjectDataSource-Assistenten Informationen zur Verfügung, die angeben, welche Klassen und Methoden in den Schritten des Assistenten angezeigt werden sollen. Da auf die CL-Klassen und -Methoden von einer ObjectDataSource in der Präsentationsebene aus zugegriffen wird, habe ich diese Attribute hinzugefügt, um die Entwurfszeiterfahrung zu verbessern. Eine ausführlichere Beschreibung dieser Attribute und ihrer Auswirkungen finden Sie im Tutorial Erstellen einer Geschäftslogikebene .

In den GetProducts() Methoden und GetProductsByCategoryID(categoryID) werden die von der GetCacheItem(key) -Methode zurückgegebenen Daten einer lokalen Variablen zugewiesen. Die GetCacheItem(key) -Methode, die wir in Kürze untersuchen werden, gibt basierend auf dem angegebenen Schlüssel ein bestimmtes Element aus dem Cache zurück. Wenn keine solchen Daten im Cache gefunden werden, werden sie aus der entsprechenden ProductsBLL Klassenmethode abgerufen und dann mithilfe der AddCacheItem(key, value) -Methode dem Cache hinzugefügt.

Die GetCacheItem(key) Methoden und AddCacheItem(key, value) sind mit dem Datencache zusammen und lesen bzw. schreiben Werte. Die GetCacheItem(key) -Methode ist die einfachere der beiden. Sie gibt einfach den Wert aus der Cache-Klasse mithilfe des übergebenen Schlüssels zurück:

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) verwendet nicht wie angegeben den Schlüsselwert , sondern ruft stattdessen die GetCacheKey(key) -Methode auf, die den Schlüssel zurückgibt, dem ProductsCache- vorangestellt ist. Der MasterCacheKeyArray, der die Zeichenfolge ProductsCache enthält, wird auch von der AddCacheItem(key, value) -Methode verwendet, wie wir kurz sehen werden.

Von einer ASP.NET CodeBehind-Klasse der Seite aus kann auf den Datencache mit der Eigenschaft s Cacheder Page Klasse zugegriffen werden, und es ermöglicht Syntax wie Cache("key") = value, wie in Schritt 2 erläutert. Über eine Klasse innerhalb der Architektur kann mit HttpRuntime.Cache oder HttpContext.Current.Cacheauf den Datencache zugegriffen werden. Peter Johnsons Blogeintrag HttpRuntime.Cache vs. HttpContext.Current.Cache weist auf den geringfügigen Leistungsvorteil bei der Verwendung HttpRuntime von anstelle von HttpContext.Currenthin. ProductsCLHttpRuntime

Hinweis

Wenn Ihre Architektur mithilfe von Klassenbibliotheksprojekten implementiert wird, müssen Sie einen Verweis auf die System.Web Assembly hinzufügen, um die HttpRuntime Klassen und HttpContext verwenden zu können.

Wenn das Element nicht im Cache gefunden wird, rufen die Methoden der ProductsCL Klasse die Daten aus der BLL ab und fügen sie dem Cache mithilfe der AddCacheItem(key, value) -Methode hinzu. Um dem Cache einen Wert hinzuzufügen, können wir den folgenden Code verwenden, der einen Zeitablauf von 60 Sekunden verwendet:

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) gibt den zeitbasierten Ablauf von 60 Sekunden in der Zukunft an, und System.Web.Caching.Cache.NoSlidingExpiration gibt an, dass kein gleitender Ablauf vorliegt. Diese Insert Methodenüberladung verfügt zwar über Eingabeparameter sowohl für einen absoluten als auch für einen gleitenden Ablauf, Sie können jedoch nur einen der beiden angeben. Wenn Sie versuchen, sowohl eine absolute Zeit als auch eine Zeitspanne anzugeben, löst die Insert Methode eine Ausnahme aus ArgumentException .

Hinweis

Diese Implementierung der AddCacheItem(key, value) Methode weist derzeit einige Mängel auf. Diese Probleme werden in Schritt 4 behandelt und behoben.

Schritt 4: Ungültiger Cache, wenn die Daten über die Architektur geändert werden

Zusammen mit Den Methoden zum Abrufen von Daten muss die Cacheebene die gleichen Methoden wie die BLL zum Einfügen, Aktualisieren und Löschen von Daten bereitstellen. Die Datenänderungsmethoden der CL ändern nicht die zwischengespeicherten Daten, sondern rufen stattdessen die entsprechende Datenänderungsmethode der BLL auf, und dann wird der Cache ungültig. Wie wir im vorherigen Tutorial gesehen haben, ist dies dasselbe Verhalten, das objectDataSource anwendet, wenn die Zwischenspeicherungsfeatures aktiviert sind und die InsertMethoden , Updateoder Delete aufgerufen werden.

Die folgende UpdateProduct Überladung veranschaulicht, wie die Datenänderungsmethoden in der CL implementiert werden:

<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

Die entsprechende Datenänderungsmethode Business Logic Layer wird aufgerufen, aber bevor die Antwort zurückgegeben wird, müssen wir den Cache ungültig machen. Leider ist das Ungültiglegen des Caches nicht einfach, da die ProductsCL Klassen s GetProducts() und GetProductsByCategoryID(categoryID) Methoden jeweils Elemente mit unterschiedlichen Schlüsseln zum Cache hinzufügen und die GetProductsByCategoryID(categoryID) Methode für jede eindeutige categoryID ein anderes Cacheelement hinzufügt.

Wenn sie den Cache ungültig machen, müssen wir alle Elemente entfernen, die möglicherweise von der ProductsCL -Klasse hinzugefügt wurden. Dies kann erreicht werden, indem den einzelnen Elementen, die dem Cache in der AddCacheItem(key, value) -Methode hinzugefügt werden, eine Cacheabhängigkeit zugeordnet wird. Im Allgemeinen kann eine Cacheabhängigkeit ein anderes Element im Cache, eine Datei im Dateisystem oder Daten aus einer Microsoft SQL Server-Datenbank sein. Wenn sich die Abhängigkeit ändert oder aus dem Cache entfernt wird, werden die Cacheelemente, denen sie zugeordnet ist, automatisch aus dem Cache entfernt. In diesem Tutorial möchten wir ein zusätzliches Element im Cache erstellen, das als Cacheabhängigkeit für alle Elemente dient, die über die ProductsCL -Klasse hinzugefügt wurden. Auf diese Weise können alle diese Elemente aus dem Cache entfernt werden, indem Sie einfach die Cacheabhängigkeit entfernen.

Aktualisieren Sie die AddCacheItem(key, value) -Methode, sodass jedes Element, das dem Cache über diese Methode hinzugefügt wird, einer einzelnen Cacheabhängigkeit zugeordnet ist:

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 ist ein Zeichenfolgenarray, das einen einzelnen Wert enthält, ProductsCache. Zunächst wird dem Cache ein Cacheelement hinzugefügt und dem aktuellen Datum und der aktuellen Uhrzeit zugewiesen. Wenn das Cacheelement bereits vorhanden ist, wird es aktualisiert. Als Nächstes wird eine Cacheabhängigkeit erstellt. Der CacheDependency Konstruktor der Klasse weist eine Reihe von Überladungen auf, aber der hier verwendete Konstruktor erwartet zwei String Arrayeingaben. Der erste gibt den Satz von Dateien an, die als Abhängigkeiten verwendet werden sollen. Da wir keine dateibasierten Abhängigkeiten verwenden möchten, wird für den ersten Eingabeparameter der Wert von Nothing verwendet. Der zweite Eingabeparameter gibt den Satz von Cacheschlüsseln an, die als Abhängigkeiten verwendet werden sollen. Hier geben wir unsere einzelne Abhängigkeit an. MasterCacheKeyArray Der CacheDependency wird dann an die Insert -Methode übergeben.

Mit dieser Änderung an AddCacheItem(key, value)ist das Ungültigen des Caches so einfach wie das Entfernen der Abhängigkeit.

<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

Schritt 5: Aufrufen der Zwischenspeicherebene von der Präsentationsebene

Die Klassen und Methoden der Caching-Schicht können zum Arbeiten mit Daten mithilfe der Techniken verwendet werden, die wir in diesen Tutorials untersucht haben. Um die Arbeit mit zwischengespeicherten Daten zu veranschaulichen, speichern Sie Ihre Änderungen an der ProductsCL -Klasse, öffnen Sie dann die FromTheArchitecture.aspx Seite im Caching Ordner, und fügen Sie eine GridView hinzu. Erstellen Sie über das Smarttag von GridView eine neue ObjectDataSource. Im ersten Schritt des Assistenten sollte die ProductsCL Klasse als eine der Optionen aus der Dropdownliste angezeigt werden.

Die ProductsCL-Klasse ist in der Liste

Abbildung 4: Die ProductsCL Klasse ist in der Liste "Business Object Drop-Down" enthalten (Klicken Sie hier, um das bild in voller Größe anzuzeigen).

Nachdem Sie ausgewählt haben ProductsCL, klicken Sie auf Weiter. Die Dropdownliste auf der Registerkarte SELECT enthält zwei Elemente – GetProducts() und GetProductsByCategoryID(categoryID) die Registerkarte UPDATE hat die einzige UpdateProduct Überladung. Wählen Sie die GetProducts() -Methode auf der Registerkarte SELECT und die UpdateProducts -Methode auf der Registerkarte UPDATE aus, und klicken Sie auf Fertig stellen.

Die Methoden der ProductsCL-Klasse sind im Drop-Down Listen

Abbildung 5: Die ProductsCL Methoden der Klasse werden in der Drop-Down Listen aufgeführt (Klicken Sie, um das vollständige Bild anzuzeigen)

Nach Abschluss des Assistenten legt Visual Studio die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0} fest und fügt der GridView die entsprechenden Felder hinzu. Ändern Sie die OldValuesParameterFormatString Eigenschaft wieder auf ihren Standardwert , {0}und konfigurieren Sie GridView so, dass Paging, Sortierung und Bearbeitung unterstützt werden. Da die von der UploadProducts CL verwendete Überladung nur den Namen und den Preis des bearbeiteten Produkts akzeptiert, beschränken Sie gridView so, dass nur diese Felder bearbeitbar sind.

Im vorherigen Tutorial haben wir eine GridView definiert, die Felder für die ProductNameFelder , CategoryNameund UnitPrice enthält. Sie können diese Formatierung und Struktur replizieren. In diesem Fall sollte Das deklarative Markup von GridView und ObjectDataSource wie folgt aussehen:

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

An diesem Punkt haben wir eine Seite, die die Zwischenspeicherebene verwendet. Um den Cache in Aktion zu sehen, legen Sie Haltepunkte in den ProductsCL Klassen s GetProducts() und UpdateProduct Methoden fest. Besuchen Sie die Seite in einem Browser, und durchlaufen Sie den Code beim Sortieren und Paging, um die aus dem Cache abgerufenen Daten zu sehen. Aktualisieren Sie dann einen Datensatz, und beachten Sie, dass der Cache ungültig ist und daher aus der BLL abgerufen wird, wenn die Daten an die GridView-Instanz übergeben werden.

Hinweis

Die In diesem Artikel enthaltene Zwischenspeicherebene im Download ist nicht vollständig. Es enthält nur eine Klasse, ProductsCLdie nur eine Handvoll Methoden verwendet. Darüber hinaus verwendet nur eine einzelne ASP.NET Seite die CL (~/Caching/FromTheArchitecture.aspx), alle anderen verweisen weiterhin direkt auf die BLL. Wenn Sie planen, eine CL in Ihrer Anwendung zu verwenden, sollten alle Aufrufe von der Präsentationsebene an die CL gehen, was erfordert, dass die Klassen und Methoden der CL diese Klassen und Methoden in der derzeit von der Präsentationsebene verwendeten BLL abdecken.

Zusammenfassung

Während die Zwischenspeicherung auf der Präsentationsebene mit ASP.NET SqlDataSource- und ObjectDataSource-Steuerelementen von ASP.NET 2.0 s angewendet werden kann, werden zwischenspeichernde Zuständigkeiten im Idealfall auf eine separate Ebene in der Architektur delegiert. In diesem Tutorial haben wir eine Zwischenspeicherebene erstellt, die sich zwischen der Präsentationsebene und der Geschäftslogikebene befindet. Die Zwischenspeicherebene muss den gleichen Satz von Klassen und Methoden bereitstellen, die in der BLL vorhanden sind und von der Präsentationsebene aufgerufen werden.

Die Beispiele für die Caching-Schicht, die wir in diesem und den vorherigen Tutorials untersucht haben, zeigen reaktives Laden. Beim reaktiven Laden werden die Daten nur dann in den Cache geladen, wenn eine Anforderung für die Daten erfolgt und diese Daten im Cache fehlen. Daten können auch proaktiv in den Cache geladen werden, eine Technik, die die Daten in den Cache lädt, bevor sie tatsächlich benötigt werden. Im nächsten Tutorial sehen Wir ein Beispiel für proaktives Laden, wenn wir uns ansehen, wie statische Werte beim Start der Anwendung im Cache gespeichert werden.

Viel Spaß beim Programmieren!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderen Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüferin für dieses Tutorial war Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.