Verwenden von SQL-Cacheabhängigkeiten (VB)
von Scott Mitchell
Die einfachste Zwischenspeicherungsstrategie besteht darin, zuzulassen, dass zwischengespeicherte Daten nach einem bestimmten Zeitraum ablaufen. Dieser einfache Ansatz bedeutet jedoch, dass die zwischengespeicherten Daten keine Zuordnung zu ihrer zugrunde liegenden Datenquelle beibehalten, was zu veralteten Daten führt, die zu lange aufbewahrt werden, oder aktuelle Daten, die zu früh abgelaufen sind. Ein besserer Ansatz besteht darin, die SqlCacheDependency-Klasse zu verwenden, sodass Die Daten zwischengespeichert bleiben, bis die zugrunde liegenden Daten in der SQL-Datenbank geändert wurden. In diesem Tutorial erfahren Sie, wie.
Einführung
Die in den Tutorials "Zwischenspeichern von Daten mit ObjectDataSource" und "Daten zwischenspeichern" in den Tutorials "Architektur" untersuchten Zwischenspeicherungstechniken verwendeten einen zeitbasierten Ablauf, um die Daten nach einem bestimmten Zeitraum aus dem Cache zu entfernen. Dieser Ansatz ist der einfachste Weg, um die Leistungsgewinne des Zwischenspeicherns mit der Veraltetkeit von Daten auszugleichen. Durch die Auswahl eines Zeitablaufs von x Sekunden, gibt ein Seitenentwickler zu, die Leistungsvorteile des Zwischenspeicherns nur für x Sekunden zu nutzen, kann aber einfach sein, dass seine Daten nie länger als maximal x Sekunden veraltet sind. Für statische Daten kann x natürlich auf die Lebensdauer der Webanwendung erweitert werden, wie im Tutorial Zwischenspeichern von Daten beim Anwendungsstart untersucht wurde.
Beim Zwischenspeichern von Datenbankdaten wird häufig ein zeitbasierter Ablauf aus Gründen der Benutzerfreundlichkeit gewählt, ist aber häufig eine unzureichende Lösung. Im Idealfall bleiben die Datenbankdaten zwischengespeichert, bis die zugrunde liegenden Daten in der Datenbank geändert wurden. nur dann würde der Cache entfernt. Dieser Ansatz maximiert die Leistungsvorteile des Zwischenspeicherns und minimiert die Dauer veralteter Daten. Um diese Vorteile nutzen zu können, muss jedoch ein System vorhanden sein, das weiß, wann die zugrunde liegenden Datenbankdaten geändert wurden, und die entsprechenden Elemente aus dem Cache entfernt. Vor ASP.NET 2.0 waren Seitenentwickler für die Implementierung dieses Systems verantwortlich.
ASP.NET 2.0 stellt eine SqlCacheDependency
Klasse und die erforderliche Infrastruktur bereit, um zu bestimmen, wann eine Änderung in der Datenbank erfolgt ist, sodass die entsprechenden zwischengespeicherten Elemente entfernt werden können. Es gibt zwei Techniken, um zu bestimmen, wann sich die zugrunde liegenden Daten geändert haben: Benachrichtigungen und Abfragen. Nachdem wir die Unterschiede zwischen Benachrichtigungen und Abfragen erläutert haben, erstellen wir die erforderliche Infrastruktur, um die Abfrage zu unterstützen, und untersuchen dann, wie die SqlCacheDependency
Klasse in deklarativen und programmgesteuerten Szenarien verwendet werden kann.
Grundlegendes zu Benachrichtigungen und Abfragen
Es gibt zwei Techniken, die verwendet werden können, um zu bestimmen, wann die Daten in einer Datenbank geändert wurden: Benachrichtigung und Abfrage. Mit der Benachrichtigung benachrichtigt die Datenbank automatisch die ASP.NET Runtime, wenn die Ergebnisse einer bestimmten Abfrage seit der letzten Ausführung der Abfrage geändert wurden, und an diesem Punkt die zwischengespeicherten Elemente, die der Abfrage zugeordnet sind, entfernt werden. Beim Abfragen verwaltet der Datenbankserver Informationen darüber, wann bestimmte Tabellen zuletzt aktualisiert wurden. Die ASP.NET Runtime fragt in regelmäßigen Abständen die Datenbank ab, um zu überprüfen, welche Tabellen sich seit der Eingabe in den Cache geändert haben. Für Tabellen, deren Daten geändert wurden, wurden die zugeordneten Cacheelemente entfernt.
Die Benachrichtigungsoption erfordert eine geringere Einrichtung als die Abfrage und ist präziser, da änderungen auf Abfrageebene und nicht auf Tabellenebene nachverfolgt werden. Leider sind Benachrichtigungen nur in den Vollversionen von Microsoft SQL Server 2005 (d. h. den Nicht-Express-Editionen) verfügbar. Die Abfrageoption kann jedoch für alle Versionen von Microsoft SQL Server von 7.0 bis 2005 verwendet werden. Da diese Tutorials die Express-Edition von SQL Server 2005 verwenden, konzentrieren wir uns auf das Einrichten und Verwenden der Abfrageoption. Weitere Ressourcen zu SQL Server Benachrichtigungsfunktionen von 2005 finden Sie im Abschnitt Weitere Informationen am Ende dieses Tutorials.
Bei der Abfrage muss die Datenbank so konfiguriert werden, dass sie eine Tabelle mit dem Namen enthält AspNet_SqlCacheTablesForChangeNotification
, die drei Spalten enthält: tableName
, notificationCreated
und changeId
. Diese Tabelle enthält eine Zeile für jede Tabelle, die Daten enthält, die möglicherweise in einer SQL-Cacheabhängigkeit in der Webanwendung verwendet werden müssen. Die tableName
Spalte gibt den Namen der Tabelle an, während notificationCreated
das Datum und die Uhrzeit des Hinzufügens der Zeile zur Tabelle angegeben werden. Die changeId
Spalte ist vom Typ int
und hat den Anfangswert 0. Sein Wert wird mit jeder Änderung der Tabelle erhöht.
Zusätzlich zur AspNet_SqlCacheTablesForChangeNotification
Tabelle muss die Datenbank auch Trigger für jede der Tabellen enthalten, die möglicherweise in einer SQL-Cacheabhängigkeit angezeigt werden. Diese Trigger werden immer dann ausgeführt, wenn eine Zeile eingefügt, aktualisiert oder gelöscht wird, und erhöhen sie den Wert der Tabelle changeId
in AspNet_SqlCacheTablesForChangeNotification
.
Die ASP.NET Runtime verfolgt den aktuellen changeId
für eine Tabelle nach, wenn Daten mithilfe eines SqlCacheDependency
-Objekts zwischengespeichert werden. Die Datenbank wird in regelmäßigen Abständen überprüft, und alle SqlCacheDependency
Objekte, deren changeId
Wert sich vom Wert in der Datenbank unterscheidet, werden entfernt, da ein unterschiedlicher changeId
Wert angibt, dass seit dem Zwischenspeichern der Daten eine Änderung an der Tabelle aufgetreten ist.
Schritt 1: Erkunden des Befehlszeilenprogrammsaspnet_regsql.exe
Beim Abfrageansatz muss die Datenbank so eingerichtet werden, dass sie die oben beschriebene Infrastruktur enthält: eine vordefinierte Tabelle (AspNet_SqlCacheTablesForChangeNotification
), eine Handvoll gespeicherter Prozeduren und Trigger für jede der Tabellen, die in SQL-Cacheabhängigkeiten in der Webanwendung verwendet werden können. Diese Tabellen, gespeicherten Prozeduren und Trigger können über das Befehlszeilenprogramm aspnet_regsql.exe
erstellt werden, das sich im $WINDOWS$\Microsoft.NET\Framework\version
Ordner befindet. Um die Tabelle und die AspNet_SqlCacheTablesForChangeNotification
zugeordneten gespeicherten Prozeduren zu erstellen, führen Sie über die Befehlszeile Folgendes aus:
/* 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
Hinweis
Zum Ausführen dieser Befehle muss sich die angegebene Datenbankanmeldung in den db_securityadmin
Rollen und db_ddladmin
befinden.
Wenn Sie beispielsweise die Infrastruktur für die Abfrage einer Microsoft SQL Server-Datenbank namens auf einem Datenbankserver namens pubs
ScottsServer
mithilfe der Windows-Authentifizierung hinzufügen möchten, navigieren Sie zum entsprechenden Verzeichnis, und geben Sie in der Befehlszeile Folgendes ein:
aspnet_regsql.exe -S ScottsServer -E -d pubs -ed
Nachdem die Infrastruktur auf Datenbankebene hinzugefügt wurde, müssen wir die Trigger zu den Tabellen hinzufügen, die in SQL-Cacheabhängigkeiten verwendet werden. Verwenden Sie das aspnet_regsql.exe
Befehlszeilenprogramm erneut, aber geben Sie den Tabellennamen mithilfe des -t
Schalters an, und verwenden Sie -et
anstelle des Schalters -ed
wie folgt:
/* 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
Um die Trigger den Tabellen und titles
in der authors
pubs
Datenbank auf ScottsServer
hinzuzufügen, verwenden Sie Folgendes:
aspnet_regsql.exe -S ScottsServer -E -d pubs -t authors -et
aspnet_regsql.exe -S ScottsServer -E -d pubs -t titles -et
Fügen Sie für dieses Tutorial die Trigger den Products
Tabellen , Categories
und Suppliers
hinzu. Wir sehen uns die bestimmte Befehlszeilensyntax in Schritt 3 an.
Schritt 2: Verweisen auf eine Microsoft SQL Server 2005 Express Edition-Datenbank inApp_Data
Das aspnet_regsql.exe
Befehlszeilenprogramm erfordert den Datenbank- und Servernamen, um die erforderliche Abrufinfrastruktur hinzuzufügen. Aber wie lautet der Datenbank- und Servername für eine Microsoft SQL Server 2005 Express-Datenbank, die App_Data
sich im Ordner befindet? Anstatt die Datenbank- und Servernamen ermitteln zu müssen, habe ich festgestellt, dass der einfachste Ansatz darin besteht, die Datenbank an die localhost\SQLExpress
Datenbank anzufügen instance und die Daten mithilfe von SQL Server Management Studio umzubenennen. Wenn Sie eine der Vollversionen von SQL Server 2005 auf Ihrem Computer installiert haben, haben Sie wahrscheinlich bereits SQL Server Management Studio auf Ihrem Computer installiert. Wenn Sie nur über die Express-Edition verfügen, können Sie die kostenlose Microsoft SQL Server Management Studio herunterladen.
Schließen Sie zunächst Visual Studio. Öffnen Sie als Nächstes SQL Server Management Studio, und stellen Sie eine Verbindung mit dem Server mithilfe der localhost\SQLExpress
Windows-Authentifizierung her.
Abbildung 1: Anfügen an den localhost\SQLExpress
Server
Nach dem Herstellen einer Verbindung mit dem Server zeigt Management Studio den Server an und verfügt über Unterordner für die Datenbanken, die Sicherheit usw. Klicken Sie mit der rechten Maustaste auf den Ordner Datenbanken, und wählen Sie die Option Anfügen aus. Dadurch wird das Dialogfeld Datenbanken anfügen geöffnet (siehe Abbildung 2). Klicken Sie auf die Schaltfläche Hinzufügen, und wählen Sie den NORTHWND.MDF
Datenbankordner im Ordner Ihrer Webanwendung aus App_Data
.
Abbildung 2: Anfügen der NORTHWND.MDF
Datenbank aus dem App_Data
Ordner (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Dadurch wird die Datenbank dem Ordner Datenbanken hinzugefügt. Der Datenbankname kann der vollständige Pfad zur Datenbankdatei oder der vollständige Pfad sein, dem eine GUID vorangestellt ist. Um zu vermeiden, dass Sie diesen langen Datenbanknamen eingeben müssen, wenn Sie das Befehlszeilentool aspnet_regsql.exe verwenden, benennen Sie die Datenbank in einen benutzerfreundlicheren Namen um, indem Sie mit der rechten Maustaste auf die gerade angefügte Datenbank klicken und Umbenennen auswählen. Ich habe meine Datenbank in DataTutorials umbenannt.
Abbildung 3: Umbenennen der angefügten Datenbank in einen Human-Friendly Namen
Schritt 3: Hinzufügen der Abfrageinfrastruktur zur Northwind-Datenbank
Nachdem wir die Datenbank aus dem NORTHWND.MDF
App_Data
Ordner angefügt haben, können wir die Abfrageinfrastruktur hinzufügen. Wenn Sie die Datenbank in DataTutorials umbenannt haben, führen Sie die folgenden vier Befehle aus:
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
Nachdem Sie diese vier Befehle ausgeführt haben, klicken Sie mit der rechten Maustaste in Management Studio auf den Datenbanknamen, wechseln Sie zum Untermenü Aufgaben, und wählen Sie Trennen aus. Schließen Sie dann Management Studio, und öffnen Sie Visual Studio erneut.
Nachdem Visual Studio erneut geöffnet wurde, führen Sie einen Drilldown in die Datenbank über den Server Explorer. Notieren Sie sich die neue Tabelle (AspNet_SqlCacheTablesForChangeNotification
), die neuen gespeicherten Prozeduren und die Trigger für die Products
Tabellen , Categories
und Suppliers
.
Abbildung 4: Die Datenbank enthält jetzt die erforderliche Abfrageinfrastruktur
Schritt 4: Konfigurieren des Abrufdiensts
Nach dem Erstellen der benötigten Tabellen, Trigger und gespeicherten Prozeduren in der Datenbank besteht der letzte Schritt darin, den Abrufdienst zu konfigurieren. Hierzu werden Web.config
die zu verwendenden Datenbanken und die Abrufhäufigkeit in Millisekunden angegeben. Das folgende Markup fragt die Northwind-Datenbank einmal pro Sekunde ab.
<?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>
Der name
Wert im <add>
Element ( NorthwindDB ) ordnet einer bestimmten Datenbank einen lesbaren Namen zu. Bei der Arbeit mit SQL-Cacheabhängigkeiten müssen wir auf den hier definierten Datenbanknamen und die Tabelle verweisen, auf der die zwischengespeicherten Daten basieren. In Schritt 6 erfahren Sie, wie Sie die SqlCacheDependency
-Klasse verwenden, um SQL-Cacheabhängigkeiten programmgesteuert mit zwischengespeicherten Daten zuzuordnen.
Sobald eine SQL-Cacheabhängigkeit eingerichtet wurde, stellt das Abfragesystem alle pollTime
Millisekunden eine Verbindung mit den in den <databases>
Elementen definierten Datenbanken her und führt die AspNet_SqlCachePollingStoredProcedure
gespeicherte Prozedur aus. Diese gespeicherte Prozedur , die in Schritt 3 mithilfe des aspnet_regsql.exe
Befehlszeilentools wieder hinzugefügt wurde, gibt die tableName
Werte und changeId
für jeden Datensatz in AspNet_SqlCacheTablesForChangeNotification
zurück. Veraltete SQL-Cacheabhängigkeiten werden aus dem Cache entfernt.
Die pollTime
Einstellung führt einen Kompromiss zwischen Leistung und Datenalter ein. Ein kleiner pollTime
Wert erhöht die Anzahl der Anforderungen an die Datenbank, räumt jedoch veraltete Daten schneller aus dem Cache. Ein größerer pollTime
Wert reduziert die Anzahl von Datenbankanforderungen, erhöht jedoch die Verzögerung zwischen dem Ändern der Back-End-Daten und dem Entfernen der zugehörigen Cacheelemente. Glücklicherweise führt die Datenbankanforderung eine einfache gespeicherte Prozedur aus, die nur einige Zeilen aus einer einfachen, einfachen Tabelle zurückgibt. Experimentieren Sie jedoch mit verschiedenen pollTime
Werten, um ein ideales Gleichgewicht zwischen Datenbankzugriff und Datenalter für Ihre Anwendung zu finden. Der kleinste pollTime
zulässige Wert ist 500.
Hinweis
Im obigen Beispiel wird ein einzelner pollTime
Wert im <sqlCacheDependency>
Element bereitgestellt, sie können jedoch optional den pollTime
Wert im <add>
-Element angeben. Dies ist nützlich, wenn Sie mehrere Datenbanken angegeben haben und die Abrufhäufigkeit pro Datenbank anpassen möchten.
Schritt 5: Deklaratives Arbeiten mit SQL-Cacheabhängigkeiten
In den Schritten 1 bis 4 haben wir uns mit dem Einrichten der erforderlichen Datenbankinfrastruktur und dem Konfigurieren des Abfragesystems befasst. Wenn diese Infrastruktur vorhanden ist, können wir dem Datencache nun Elemente mit einer zugeordneten SQL-Cacheabhängigkeit hinzufügen, indem wir entweder programmgesteuerte oder deklarative Techniken verwenden. In diesem Schritt wird die deklarative Arbeit mit SQL-Cacheabhängigkeiten untersucht. In Schritt 6 sehen wir uns den programmgesteuerten Ansatz an.
Im Tutorial Zwischenspeichern von Daten mit ObjectDataSource wurden die deklarativen Zwischenspeicherungsfunktionen von ObjectDataSource untersucht. Indem Sie einfach die EnableCaching
-Eigenschaft auf True
und die CacheDuration
-Eigenschaft auf ein bestimmtes Zeitintervall festlegen, speichert die ObjectDataSource automatisch die von ihrem zugrunde liegenden Objekt zurückgegebenen Daten für das angegebene Intervall zwischen. Die ObjectDataSource kann auch eine oder mehrere SQL-Cacheabhängigkeiten verwenden.
Um die Verwendung von SQL-Cacheabhängigkeiten deklarativ zu veranschaulichen, öffnen Sie die SqlCacheDependencies.aspx
Seite im Caching
Ordner, und ziehen Sie eine GridView aus der Toolbox auf die Designer. Legen Sie die GridView s ID
auf ProductsDeclarative
fest, und wählen Sie aus dem Smarttag aus, um es an eine neue ObjectDataSource mit dem Namen ProductsDataSourceDeclarative
zu binden.
Abbildung 5: Erstellen eines neuen ObjectDataSource-Namens ProductsDataSourceDeclarative
(Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Konfigurieren Sie objectDataSource für die Verwendung der ProductsBLL
-Klasse, und legen Sie die Dropdownliste auf der Registerkarte SELECT auf fest GetProducts()
. Wählen Sie auf der Registerkarte UPDATE die UpdateProduct
Überladung mit den drei Eingabeparametern productName
, unitPrice
und productID
aus. Legen Sie die Dropdownlisten auf den Registerkarten INSERT und DELETE auf (Keine) fest.
Abbildung 6: Verwenden der UpdateProduct-Überladung mit drei Eingabeparametern (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Abbildung 7: Festlegen der Drop-Down Liste auf (Keine) für die Registerkarten INSERT und DELETE (Klicken, um das bild in voller Größe anzuzeigen)
Nach Abschluss des Assistenten Zum Konfigurieren von Datenquellen erstellt Visual Studio BoundFields und CheckBoxFields in gridView für jedes Datenfeld. Entfernen Sie alle Felder außer ProductName
, CategoryName
und , und UnitPrice
formatieren Sie diese Felder nach Bedarf. Aktivieren Sie im Smarttag von GridView die Kontrollkästchen Paging aktivieren, Sortierung aktivieren und Bearbeitung aktivieren. Visual Studio legt die ObjectDataSource-Eigenschaft OldValuesParameterFormatString
auf fest original_{0}
. Damit die Bearbeitungsfunktion von GridView ordnungsgemäß funktioniert, entfernen Sie diese Eigenschaft entweder vollständig aus der deklarativen Syntax, oder legen Sie sie wieder auf ihren Standardwert fest. {0}
Fügen Sie schließlich ein Label Web-Steuerelement über der GridView hinzu, und legen Sie seine ID
Eigenschaft auf ODSEvents
und seine EnableViewState
Eigenschaft auf False
fest. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup Ihrer Seite wie folgt aussehen. Beachten Sie, dass ich eine Reihe von ästhetischen Anpassungen an die GridView-Felder vorgenommen habe, die nicht erforderlich sind, um die SQL-Cacheabhängigkeitsfunktionalität zu demonstrieren.
<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>
Erstellen Sie als Nächstes einen Ereignishandler für das ObjectDataSource-Ereignis, Selecting
und fügen Sie darin den folgenden Code hinzu:
Protected Sub ProductsDataSourceDeclarative_Selecting _
(sender As Object, e As ObjectDataSourceSelectingEventArgs) _
Handles ProductsDataSourceDeclarative.Selecting
ODSEvents.Text = "-- Selecting event fired"
End Sub
Denken Sie daran, dass das ObjectDataSource-Ereignis Selecting
nur beim Abrufen von Daten aus dem zugrunde liegenden Objekt ausgelöst wird. Wenn ObjectDataSource über einen eigenen Cache auf die Daten zugreift, wird dieses Ereignis nicht ausgelöst.
Besuchen Sie diese Seite nun über einen Browser. Da wir noch keine Zwischenspeicherung implementieren müssen, sollte bei jeder Seite, Sortierung oder Bearbeitung des Rasters der Text angezeigt werden: "Ereignisauswahl ausgelöst, wie Abbildung 8 zeigt.
Abbildung 8: Das ObjectDataSource-Ereignis Selecting
wird jedes Mal ausgelöst, wenn die GridView ausgelagert, bearbeitet oder sortiert wird (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Wie wir im Tutorial Zwischenspeichern von Daten mit dem ObjectDataSource-Tutorial gezeigt haben, bewirkt das Festlegen der EnableCaching
Eigenschaft auf True
, dass objectDataSource ihre Daten für die von der CacheDuration
-Eigenschaft angegebene Dauer zwischenspeichert. Die ObjectDataSource verfügt auch über eine SqlCacheDependency
-Eigenschaft, die den zwischengespeicherten Daten mithilfe des Musters eine oder mehrere SQL-Cacheabhängigkeiten hinzufügt:
databaseName1:tableName1;databaseName2:tableName2;...
Wobei databaseName der Name der Datenbank ist, wie im name
Attribut des <add>
-Elements in Web.config
angegeben, und tableName ist der Name der Datenbanktabelle. Um beispielsweise eine ObjectDataSource zu erstellen, die Daten basierend auf einer SQL-Cacheabhängigkeit von der Tabelle Northwind s Products
unbegrenzt zwischenspeichert, legen Sie die ObjectDataSource-Eigenschaft EnableCaching
auf True
und ihre SqlCacheDependency
Eigenschaft auf NorthwindDB:Products fest.
Hinweis
Sie können eine SQL-Cacheabhängigkeit und einen zeitbasierten Ablauf verwenden, indem Sie auf True
, CacheDuration
für das Zeitintervall und SqlCacheDependency
für die Datenbank- und Tabellennamen festlegenEnableCaching
. Die ObjectDataSource entfernt ihre Daten, wenn der zeitbasierte Ablauf erreicht ist oder wenn das Abrufsystem feststellt, dass sich die zugrunde liegenden Datenbankdaten geändert haben, je nachdem, was zuerst geschieht.
Die GridView in SqlCacheDependencies.aspx
zeigt Daten aus zwei Tabellen an – Products
und Categories
(das Feld des CategoryName
Produkts wird über ein JOIN
Categories
abgerufen). Daher möchten wir zwei SQL-Cacheabhängigkeiten angeben: NorthwindDB:Products; NorthwindDB:Categories .
Abbildung 9: Konfigurieren der ObjectDataSource für die Unterstützung der Zwischenspeicherung mithilfe von SQL-Cacheabhängigkeiten auf Products
und Categories
(Klicken, um das bild in voller Größe anzuzeigen)
Nachdem Sie objectDataSource für die Unterstützung der Zwischenspeicherung konfiguriert haben, besuchen Sie die Seite über einen Browser erneut. Auch hier sollte der Text "Ereignis auswählen" auf der ersten Seite angezeigt werden, sollte aber beim Paging, Sortieren oder Klicken auf die Schaltflächen Bearbeiten oder Abbrechen verschwinden. Dies liegt daran, dass die Daten nach dem Laden in den Cache von ObjectDataSource dort verbleiben, bis die Products
Tabellen oder Categories
geändert oder die Daten über GridView aktualisiert werden.
Öffnen Sie nach dem Durchlaufen des Rasters und dem Fehlen des vom Ereignis ausgelösten Texts ein neues Browserfenster, und navigieren Sie zum Tutorial Grundlagen im Abschnitt Bearbeiten, Einfügen und Löschen (~/EditInsertDelete/Basics.aspx
). Aktualisieren Sie den Namen oder Preis eines Produkts. Zeigen Sie dann im ersten Browserfenster eine andere Datenseite an, sortieren Sie das Raster, oder klicken Sie auf die Schaltfläche Bearbeiten der Zeile. Dieses Mal sollte das ausgelöste Ereignis "Auswahlereignis" erneut angezeigt werden, da die zugrunde liegenden Datenbankdaten geändert wurden (siehe Abbildung 10). Wenn der Text nicht angezeigt wird, warten Sie einige Augenblicke, und versuchen Sie es erneut. Denken Sie daran, dass der Abrufdienst alle pollTime
Millisekunden auf Änderungen an der Products
Tabelle überprüft, sodass es zwischen dem Aktualisieren der zugrunde liegenden Daten und dem Entfernen der zwischengespeicherten Daten zu einer Verzögerung kommt.
Abbildung 10: Ändern der Tabelle "Produkte" entfernt die zwischengespeicherten Produktdaten (Klicken, um das bild in voller Größe anzuzeigen)
Schritt 6: Programmgesteuertes Arbeiten mit derSqlCacheDependency
Klasse
Im Tutorial Zum Zwischenspeichern von Daten in der Architektur wurden die Vorteile der Verwendung einer separaten Zwischenspeicherebene in der Architektur im Gegensatz zur engen Kopplung der Zwischenspeicherung mit der ObjectDataSource untersucht. In diesem Tutorial haben wir eine ProductsCL
Klasse erstellt, um das programmgesteuerte Arbeiten mit dem Datencache zu veranschaulichen. Verwenden Sie die SqlCacheDependency
-Klasse, um SQL-Cacheabhängigkeiten in der Zwischenspeicherebene zu verwenden.
Beim Abrufsystem muss ein SqlCacheDependency
Objekt einem bestimmten Datenbank- und Tabellenpaar zugeordnet sein. Mit dem folgenden Code wird beispielsweise ein SqlCacheDependency
Objekt basierend auf der Tabelle der Northwind-Datenbank Products
erstellt:
Dim productsTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Products")
Die beiden Eingabeparameter für den SqlCacheDependency
s-Konstruktor sind die Datenbank- bzw. Tabellennamen. Wie bei der ObjectDataSource-Eigenschaft SqlCacheDependency
ist der verwendete Datenbankname mit dem im Attribut des <add>
-Elements in name
Web.config
angegebenen Wert identisch. Der Tabellenname ist der tatsächliche Name der Datenbanktabelle.
Um ein SqlCacheDependency
einem Element zuzuordnen, das dem Datencache hinzugefügt wurde, verwenden Sie eine der Methodenüberladungen, die Insert
eine Abhängigkeit akzeptiert. Der folgende Code fügt dem Datencache auf unbestimmte Zeit einen Wert hinzu, ordnet ihn jedoch einem SqlCacheDependency
in der Products
Tabelle zu. Kurz gesagt, der Wert verbleibt im Cache, bis er aufgrund von Speichereinschränkungen entfernt wird oder weil das Abrufsystem erkannt hat, dass sich die Tabelle seit dem Products
Zwischenspeichern geändert hat.
Dim productsTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Products")
Cache.Insert(key, _
value, _
productsTableDependency, _
System.Web.Caching.Cache.NoAbsoluteExpiration, _
System.Web.Caching.Cache.NoSlidingExpiration)
Die Caching Layer-Klasse ProductsCL
speichert derzeit Daten aus der Products
Tabelle unter Verwendung eines zeitbasierten Ablaufs von 60 Sekunden zwischen. Aktualisieren Sie diese Klasse so, dass sie stattdessen SQL-Cacheabhängigkeiten verwendet. Die ProductsCL
Methode s AddCacheItem
der Klasse, die für das Hinzufügen der Daten zum Cache verantwortlich ist, enthält derzeit den folgenden Code:
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
Aktualisieren Sie diesen Code so, dass anstelle der MasterCacheKeyArray
Cacheabhängigkeit ein SqlCacheDependency
-Objekt verwendet wird:
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
Um diese Funktionalität zu testen, fügen Sie der Seite unter der vorhandenen ProductsDeclarative
GridView eine GridView hinzu. Legen Sie diese neuen GridViews ID
auf fest ProductsProgrammatic
, und binden Sie sie über das Smarttag an eine neue ObjectDataSource mit dem Namen ProductsDataSourceProgrammatic
. Konfigurieren Sie die ObjectDataSource für die Verwendung der ProductsCL
-Klasse, und legen Sie die Dropdownlisten auf den Registerkarten SELECT und UPDATE auf bzwUpdateProduct
. festGetProducts
.
Abbildung 11: Konfigurieren der ObjectDataSource für die Verwendung der ProductsCL
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Abbildung 12: Wählen Sie die GetProducts
Methode aus der Drop-Down Liste der REGISTERKARTE SELECT aus (Klicken Sie, um das bild in voller Größe anzuzeigen)
Abbildung 13: Wählen Sie die UpdateProduct-Methode aus der Drop-Down Liste der REGISTERKARTE UPDATE aus (Klicken Sie, um das bild in voller Größe anzuzeigen)
Nach Abschluss des Assistenten Zum Konfigurieren von Datenquellen erstellt Visual Studio BoundFields und CheckBoxFields in gridView für jedes Datenfeld. Entfernen Sie wie bei der ersten GridView dieser Seite alle Felder außer ProductName
, CategoryName
und , und UnitPrice
, und formatieren Sie diese Felder nach Bedarf. Aktivieren Sie im Smarttag von GridView die Kontrollkästchen Paging aktivieren, Sortierung aktivieren und Bearbeitung aktivieren. Wie bei ObjectDataSource ProductsDataSourceDeclarative
legt Visual Studio die ProductsDataSourceProgrammatic
ObjectDataSource-Eigenschaft OldValuesParameterFormatString
auf fest original_{0}
. Damit die Bearbeitungsfunktion von GridView ordnungsgemäß funktioniert, legen Sie diese Eigenschaft wieder auf {0}
fest (oder entfernen Sie die Eigenschaftszuweisung vollständig aus der deklarativen Syntax).
Nach Abschluss dieser Aufgaben sollte das resultierende deklarative GridView- und ObjectDataSource-Markup wie folgt aussehen:
<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>
Um die SQL-Cacheabhängigkeit in der Zwischenspeicherebene zu testen, legen Sie einen Haltepunkt in der Methode der ProductCL
Klasse s AddCacheItem
fest, und starten Sie dann das Debuggen. Beim ersten Besuch SqlCacheDependencies.aspx
sollte der Haltepunkt erreicht werden, da die Daten zum ersten Mal angefordert und im Cache abgelegt werden. Wechseln Sie als Nächstes zu einer anderen Seite in GridView, oder sortieren Sie eine der Spalten. Dies führt dazu, dass gridView seine Daten erneut abfragen, aber die Daten sollten im Cache gefunden werden, da die Products
Datenbanktabelle nicht geändert wurde. Wenn die Daten wiederholt nicht im Cache gefunden werden, stellen Sie sicher, dass auf Ihrem Computer genügend Arbeitsspeicher verfügbar ist, und versuchen Sie es erneut.
Nachdem Sie einige Seiten der GridView durchlaufen haben, öffnen Sie ein zweites Browserfenster, und navigieren Sie zum Tutorial Grundlagen im Abschnitt Bearbeiten, Einfügen und Löschen (~/EditInsertDelete/Basics.aspx
). Aktualisieren Sie einen Datensatz aus der Tabelle Products, und zeigen Sie dann im ersten Browserfenster eine neue Seite an, oder klicken Sie auf eine der Sortierheader.
In diesem Szenario sehen Sie eines von zwei Dingen: Entweder wird der Haltepunkt erreicht, der angibt, dass die zwischengespeicherten Daten aufgrund der Änderung in der Datenbank entfernt wurden; oder, der Haltepunkt wird nicht erreicht, was bedeutet, dass SqlCacheDependencies.aspx
jetzt veraltete Daten angezeigt werden. Wenn der Haltepunkt nicht erreicht wird, liegt dies wahrscheinlich daran, dass der Abrufdienst noch nicht ausgelöst wurde, seit die Daten geändert wurden. Denken Sie daran, dass der Abrufdienst alle pollTime
Millisekunden auf Änderungen an der Products
Tabelle überprüft, sodass es zwischen dem Aktualisieren der zugrunde liegenden Daten und dem Entfernen der zwischengespeicherten Daten zu einer Verzögerung kommt.
Hinweis
Diese Verzögerung tritt eher beim Bearbeiten eines der Produkte über die GridView in auf SqlCacheDependencies.aspx
. Im Tutorial Zwischenspeichern von Daten im Architektur-Tutorial haben wir die MasterCacheKeyArray
Cacheabhängigkeit hinzugefügt, um sicherzustellen, dass die Daten, die über die Methode der ProductsCL
Klasse s UpdateProduct
bearbeitet werden, aus dem Cache entfernt wurden. Diese Cacheabhängigkeit haben wir jedoch beim Ändern der AddCacheItem
Methode zuvor in diesem Schritt ersetzt. Daher zeigt die ProductsCL
Klasse weiterhin die zwischengespeicherten Daten an, bis das Abfragesystem die Änderung an der Products
Tabelle notiert. In Schritt 7 erfahren Sie, wie Sie die MasterCacheKeyArray
Cacheabhängigkeit wieder einführen.
Schritt 7: Zuordnen mehrerer Abhängigkeiten zu einem zwischengespeicherten Element
Denken Sie daran, dass die MasterCacheKeyArray
Cacheabhängigkeit verwendet wird, um sicherzustellen, dass alle produktbezogenen Daten aus dem Cache entfernt werden, wenn ein einzelnes element, das darin zugeordnet ist, aktualisiert wird. Beispielsweise speichert die GetProductsByCategoryID(categoryID)
-Methode Instanzen für jeden eindeutigen ProductsDataTables
categoryID-Wert zwischen. Wenn eines dieser Objekte entfernt wird, stellt die MasterCacheKeyArray
Cacheabhängigkeit sicher, dass die anderen objekte ebenfalls entfernt werden. Ohne diese Cacheabhängigkeit besteht beim Ändern der zwischengespeicherten Daten die Möglichkeit, dass andere zwischengespeicherte Produktdaten veraltet sind. Daher ist es wichtig, dass wir die Cacheabhängigkeit bei Verwendung von MasterCacheKeyArray
SQL-Cacheabhängigkeiten beibehalten. Die Methode s des Datencaches Insert
lässt jedoch nur ein einzelnes Abhängigkeitsobjekt zu.
Darüber hinaus müssen wir beim Arbeiten mit SQL-Cacheabhängigkeiten möglicherweise mehrere Datenbanktabellen als Abhängigkeiten zuordnen. Die in der ProductsDataTable
ProductsCL
-Klasse zwischengespeicherte enthält beispielsweise die Kategorie- und Lieferantennamen für jedes Produkt, aber die AddCacheItem
Methode verwendet nur eine Abhängigkeit von Products
. Wenn der Benutzer in dieser Situation den Namen einer Kategorie oder eines Lieferanten aktualisiert, verbleiben die zwischengespeicherten Produktdaten im Cache und sind veraltet. Daher möchten wir die zwischengespeicherten Produktdaten nicht nur von der Products
Tabelle, sondern auch von den Categories
Tabellen und Suppliers
abhängig machen.
Die AggregateCacheDependency
-Klasse bietet ein Mittel zum Zuordnen mehrerer Abhängigkeiten zu einem Cacheelement. Erstellen Sie zunächst eine AggregateCacheDependency
instance. Fügen Sie als Nächstes den Satz von Abhängigkeiten mithilfe der AggregateCacheDependency
s-Methode Add
hinzu. Wenn Sie das Element anschließend in den Datencache einfügen, übergeben Sie die AggregateCacheDependency
instance. Wenn sich eine der AggregateCacheDependency
Abhängigkeiten der instance ändert, wird das zwischengespeicherte Element entfernt.
Im Folgenden wird der aktualisierte Code für die ProductsCL
Methode der Klasse s AddCacheItem
veranschaulicht. Die -Methode erstellt die MasterCacheKeyArray
Cacheabhängigkeit zusammen mit SqlCacheDependency
Objekten für die Products
Tabellen , Categories
und Suppliers
. Diese werden alle zu einem AggregateCacheDependency
Objekt namens aggregateDependencies
kombiniert, das dann an die Insert
-Methode übergeben wird.
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
Testen Sie diesen neuen Code. Änderungen an den Products
Tabellen , oder Suppliers
führen nun dazu, Categories
dass die zwischengespeicherten Daten entfernt werden. Darüber hinaus entfernt die Methode s UpdateProduct
der ProductsCL
Klasse, die beim Bearbeiten eines Produkts über gridView aufgerufen wird, die MasterCacheKeyArray
Cacheabhängigkeit, wodurch die zwischengespeicherten ProductsDataTable
entfernt und die Daten bei der nächsten Anforderung erneut abgerufen werden.
Hinweis
SQL-Cacheabhängigkeiten können auch beim Ausgabezwischenspeichern verwendet werden. Eine Demonstration dieser Funktionalität finden Sie unter Verwenden ASP.NET Ausgabezwischenspeicherung mit SQL Server.
Zusammenfassung
Beim Zwischenspeichern von Datenbankdaten verbleiben die Daten im Idealfall im Cache, bis sie in der Datenbank geändert werden. Mit ASP.NET 2.0 können SQL-Cacheabhängigkeiten sowohl in deklarativen als auch in programmgesteuerten Szenarien erstellt und verwendet werden. Eine der Herausforderungen bei diesem Ansatz besteht darin, zu ermitteln, wann die Daten geändert wurden. Die Vollversionen von Microsoft SQL Server 2005 bieten Benachrichtigungsfunktionen, die eine Anwendung warnen können, wenn sich ein Abfrageergebnis geändert hat. Für die Express Edition von SQL Server 2005 und älteren Versionen von SQL Server muss stattdessen ein Abfragesystem verwendet werden. Glücklicherweise ist die Einrichtung der erforderlichen Umfrageinfrastruktur ziemlich einfach.
Viel Spaß beim Programmieren!
Weitere Informationen
Weitere Informationen zu den in diesem Tutorial erläuterten Themen finden Sie in den folgenden Ressourcen:
- Verwenden von Abfragebenachrichtigungen in Microsoft SQL Server 2005
- Erstellen einer Abfragebenachrichtigung
- Zwischenspeichern in ASP.NET mit der
SqlCacheDependency
-Klasse - ASP.NET SQL Server Registrierungstool (
aspnet_regsql.exe
) - Übersicht
SqlCacheDependency
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. Hauptprüfer für dieses Tutorial waren Marko Rangel, Teresa Murphy und Hilton Giesenow. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.