Tải bản đầy đủ (.pdf) (10 trang)

Professional ASP.NET 3.5 in C# and Visual Basic Part 114 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (308.44 KB, 10 trang )

Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1089
Chapter 23: Caching
Go ahead and enable both the Customers and Product tables. You run the command once per table. After
a table is successfully enabled, you receive the following response:
Enabling the table for SQL cache dependency.
.
Finished.
After the table is enabled, you can begin using the SQL cache invalidation features. However, before you
do, the following section shows you what happens to SQL Server when you enable these features.
Looking at SQL Server 2000
Now that the Northwind database and the Customers and Products tables have all been enabled for SQL
cache invalidation, look at what has happened in SQL Server. If you open up the SQL Server Enterprise
Manager, you see a new table contained within the Northwind database —
AspNet_SqlCacheTablesFor-
ChangeNotification
(whew, that’s a long one!). Your screen should look like Figure 23-4. Note that SQL
Server 2000 isn’t supported on Vista, so this is a screenshot of a remote SQL 2000 machine viewed from
the SQL Management Studio running on Vista.
Figure 23-4
At the top of the list of tables in the right-hand pane, you see the
AspNet_SqlCacheTablesForChange-
Notification
table. This is the table that ASP.NET uses to learn which tables are being monitored for
1089
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1090
Chapter 23: Caching
change notification and also to make note of any changes to the tables being monitored. The table is
actually quite simple when you look at the details, as illustrated in Figure 23-5.
Figure 23-5
In this figure, you can see three columns in this new table. The first is the
tableName


column. This column
simply shows a
String
reference to the names of the tables contained in the same database. Any table
named here is enabled for SQL cache invalidation.
The second column,
notificationCreated
, shows the date and time when the table was enabled for
SQL cache invalidation. The final column,
changeId
, is used to communicate to ASP.NET any changes to
the included tables. ASP.NET monitors this column for changes and, depending on the value, either uses
what is stored in memory or makes a new database query.
Looking at the Tables That Are Enabled
Using the
aspnet_regsql.exe
tool, you can see (by using a simple command) which tables are enabled
in a particular database. If you are working through the preceding examples, you see that so far you have
enabled the Customers and Products tables of the Northwind database. To get a list of the tables that are
enabled, use something similar to the following command:
aspnet_regsql.exe -S localhost -U sa -P password -d Northwind -lt
The
-lt
command produces a simple list of tables enabled for SQL cache invalidation. Inputting this
command produces the following results:
Listing all tables enabled for SQL cache dependency:
Customers
Products
Disabling a Table for SQL Server Cache Invalidation
Now that you know how to enable your SQL Server database f or SQL Server cache invalidation, take a

look at how you remove the capability for a specific table to be monitored for this process. To remove a
table from the SQL Server cache invalidation process, use the
-dt
command.
In the preceding example, using the
-lt
command showed that you have both the Customers and Prod-
ucts tables enabled. Next, you remove the Products table from the process using the following command:
aspnet_regsql.exe -S localhost -U sa -P password -d Northwind -t Products –dt
1090
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1091
Chapter 23: Caching
You can see t hat all you do is specify the name of the table using the
-t
command followed by a
-dt
command (disable table). The command line for disabling table caching will again list the tables that
are enabled for SQL Server cache invalidation; this time, the Products table is not listed — instead, Cus-
tomers, the only enabled table, is listed.
Disabling a Database for SQL Server Cache Invalidation
Not only can you pick and choose the tables that you want to remove from the process, but you can also
disable the entire database for SQL Server cache invalidation. In order to disable an entire database, you
use the
-dd
command (disable database).
Note that disabling an entire database for SQL Server cache invalidation also means that every single
table contained within this database is also disabled.
This example shows the Northwind database being disabled on my computer:
C:
\>

aspnet_regsql -S localhost -U sa -P wrox -d Northwind -dd
Disabling the database for SQL cache dependency.

Finished.
To ensure that the table is no longer enabled for SQL Server cache invalidation, we attempted to list the
tables that were enabled for cache invalidation using the
-lt
command. We received the following error:
C:
\ >
aspnet_regsql -S localhost -U sa -P wrox -d Northwind -lt
An error has happened. Details of the exception:
The database is not enabled for SQL cache notification. To enable a database for
SQL cache notification, please use SQLCacheDependencyAdmin.EnableNotifications
method, or the command line tool aspnet_regsql.exe.
If you now open the Northwind database in the SQL Se rver Enterprise Manager, you can see that the
AspNet_SqlCacheTablesForChangeNotification
table has been removed for the database.
SQL Server 2005 Cache Invalidation
As you’ve seen, standard SQL Server 2000 cache invalidation uses a table-level mechanism using a
polling model every few seconds to monitor what tables have changed. SQL Server 2000’s technique
not only requires preparation of the database, its polling is rather expensive and its caching is quite
coarse.
SQL Server 2005 supports a different, more granular series of notification that doesn’t require polling.
Direct notification of changes is a built-in feature of SQL Server 2005 and is presented via the ADO.NET
SqlCommand
. For example:
Protected Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs)
Response.Write("Page created: " + DateTime.Now.ToLongTimeString())
Dim connStr As String =

ConfigurationManager.ConnectionStrings("AppConnectionString1").ConnectionString
SqlDependency.Start(connStr)
Dim connection As New SqlConnection(connStr)
1091
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1092
Chapter 23: Caching
Dim command as New SqlCommand("Select * FROM Customers", connection)
Dim depends as New SqlCacheDependency(command)
Connection.Open
GridView1.DataSource = command.ExecuteReader()
GridView1.DataBind()
Connection.Close
"Now, do what you want with the sqlDependency object like:
Response.AddCacheDependency(depends)
End Sub
SQL Server 2005 supports b oth programmatic and declarative techniques when caching. Use the string
"CommandNotification"
in the
OutputCache
directive to enable notification-based caching for a page
as in this example. You can specify SQL caching o ptions either programmatically or declaratively, but
not both. Note that you must first call
System.Data.SqlClient.SqlDependency.Start
, passing in the
connection string, to start the SQL notification engine.
<
%@ OutputCache Duration="3600" VaryByParam="none"
SqlDependency="CommandNotification"%
>
Or, if you’re using a SqlDataSource control from within your ASP.NET page:

<
asp:SqlDataSource EnableCaching="true" SqlCacheDependency="CommandNotification"
CacheDuration="2600" /
>
As data changes within SQL Server 2005, SQL and ADO.NET automatically invalidate data cached on
the Web server.
Configuring Your ASP.NET Application
After you enable a database for SQL Server cache invalidation and also enable a couple of tables within
this database, the next step is to configure your application for SQL Server cache invalidation.
To configure your application to work with SQL Server cache invalidation, the first step is to make some
changes to the
web.config
file. In the
web.config
file, specify that you want to work with the Northwind
database, and you want ASP.NET connected to it.
Listing 23-5 shows an example of how you should change your
web.config
file to work with SQL Server
cache invalidation. The
pollTime
attribute isn’t needed if you’re using SQL Server 2005 notification
because it uses database events instead of the polling needed for earlier versions.
Listing 23-5: Configuring the web.config file
<
configuration xmlns=" />>
<
connectionStrings
>
<

add name="AppConnectionString1" connectionString="Data Source=localhost;
1092
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1093
Chapter 23: Caching
User ID=sa;Password=wrox;Database=Northwind;Persist Security Info=False"
providerName="System.Data.SqlClient" /
>
<
/connectionStrings
>
<
system.web
>
<
caching
>
<
sqlCacheDependency enabled="true"
>
<
databases
>
<
add name="Northwind" connectionStringName="AppConnectionString1"
pollTime="500" /
>
<
/databases
>
<

/sqlCacheDependency
>
<
/caching
>
<
/system.web
>
<
/configuration
>
From this listing, you can see that the first thing established is the connection string to the Northwind
database using the
<
connectionStrings
> element in the
web.config
file. Note the name of the connec-
tion string because it is utilized later in the configuration settings for SQL Server cache invalidation.
The SQL Server cache invalidation is configured using the new
<
caching
> element. This element must
be nested within the
<
system.web
> elements. Because you are working with a SQL Server cache depen-
dency, you must use a
<
sqlCacheDependency

> child node. You enable the entire process by using the
enabled = "true"
attribute. After this attribute is enabled, you work with the <
databases
> section. You
use the
<
add
> element, nested within the <
databases
> nodes, to reference the Northwind database.
The following table explains all the attributes of the
<
add
> element.
Attribute Description
Name
The
name
attribute provides an identifier to the SQL Server database.
connectionStringName
The
connectionStringName
attribute specifies the name of the connection.
Because the connection string in the preceding example is called
AppConnectionString1
, you use this value for the
connectionStringName
attribute as well.
pollTime

The
pollTime
attribute specifies the time interval from one SQL Server poll
to the next. The default is .5 seconds or 500 milliseconds (as shown in the
example). This is not needed for SQL Server 2005 notification.
Now that the
web.config
file is set up correctly, you can start using SQL Server cache invalidation on
your pages. ASP.NET makes a separate SQL Server request on a completely different thread to the
AspNet_SqlCacheTablesForChangeNotification
table to see if the
changeId
number has been incre-
mented. If the number is changed, ASP.NET knows that an underlying change has been made to the
SQL Server table and that a new result set should be retrieved. When it checks to see if it should make
a SQL Server call, the request to the small
AspNet_SqlCacheTablesForChangeNotification
table has a
single result. With SQL Server cache invalidation enabled, this is done so quickly that you really notice
the difference.
1093
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1094
Chapter 23: Caching
Testing SQL Ser ver Cache Invalidation
Now that the
web.config
file is set up and ready to go, the next step is to actually apply these new capa-
bilities to a page. Listing 23-6 is an example of a page using the SQL Server cache invalidation process.
Listing 23-6: An ASP.NET page utilizing SQL Server cache invalidation
VB

<
%@ Page Language="VB" %
>
<
%@ OutputCache Duration="3600" VaryByParam="none"
SqlDependency="Northwind:Customers"%
>
<
script runat="server"
>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Label1.Text = "Page created at " & DateTime.Now.ToShortTimeString ()
End Sub
<
/script
>
<
html xmlns=" />>
<
head runat="server"
>
<
title
>
Sql Cache Invalidation
<
/title
>
<
/head

>
<
body
>
<
form id="form1" runat="server"
>
<
asp:Label ID="Label1" Runat="server"
><
/asp:Label
><
br /
>
<
br /
>
<
asp:GridView ID="GridView1" Runat="server" DataSourceID="SqlDataSource1"
>
<
/asp:GridView
>
<
asp:SqlDataSource ID="SqlDataSource1" Runat="server"
SelectCommand="Select * From Customers"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>

"
ProviderName="
<
%$ ConnectionStrings:AppConnectionString1.providername %
>
"
>
<
/asp:SqlDataSource
>
<
/form
>
<
/body
>
<
/html
>
C#
<
%@ Page Language="C#" %
>
<
%@ OutputCache Duration="3600" VaryByParam="none"
SqlDependency="Northwind:Customers"%
>
<
script runat="server"
>

protected void Page_Load(object sender, System.EventArgs e)
{
Label1.Text = "Page created at " + DateTime.Now.ToShortTimeString();
}
<
/script
>
The first and most important part of this page is the
OuputCache
page directive that is specified at the top
of the file. Typically, the
OutputCache
directive specifies how long the page output is held in the cache
using the
Duration
attribute. Next is the
VaryByParam
attribute. The new addition is the
SqlDependency
1094
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1095
Chapter 23: Caching
attribute. This enables a particular page to use SQL Server cache invalidation. The following line shows
the format of the value for the
SqlDependency
attribute:
SqlDependency="database:table"
The value of
Northwind:Customers
specifies that you want the SQL Server cache invalidation enabled for

the Customers table within the Northwind database. The
Duration
attribute of the
OutputCache
directive
shows you that, typically, the output of this page is stored in the cache for a long time — but this cache
is invalidated immediately if the Customers table has any underlying changes made to the data that
it contains.
A change to any of the cells in the Customers table of the Northwind database invalidates the cache,
and a new cache is generated from the result, which now contains a new SQL Server database request.
Figure 23-6 shows an example of the page generated the first time it is run.
Figure 23-6
From this figure, you can see the contents of the customer with the
CustomerID
of
ALFKI
. For this entry,
go to SQL Server and change the value of the
ContactName
from
Maria Anders
to
Mary Anders
.Ifwe
weren’t using SQL Server cache invalidation, this change would have done nothing to the output cache.
The original page output in the cache would still be present and the end user would still see the
Maria
Anders
entry for the duration specified in the page’s
OutputCache

directive. But because we’re using SQL
Server cache invalidation, after the underlying information in the table is changed, the output cache is
invalidated, a new result set is retrieved, and the new result set is cached. When a change has been made,
you see the results as shown in Figure 23-7.
1095
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1096
Chapter 23: Caching
Figure 23-7
Notice also that the text ’’Page created at’’ includes an updated time indicating when this page was
rendered. Need to stop working so late, eh?
Adding More Than One Table to a Page
The preceding example shows how to use SQL Server cache invalidation for a single table on the
ASP.NET page. What do you do if your page is working with two or more tables?
To add more than one table, you use the
OutputCache
directive shown here:
SqlDependency="database:table;database:table"
From this example, you can see that the value of the
SqlDependency
attribute separates the databases
and tables with a semicolon. If you want to work with both the Customers table and the Products table
of the Northwind database, you construct the value of the
SqlDependency
attribute as follows:
SqlDependency="Northwind:Customers;Northwind:Products"
Attaching SQL Server Cache Dependencies
to the Request Object
In addition to changing settings in the
OutputCache
directive to activate SQL Server cache invalidation,

you can also set the SQL Server cache invalidation programmatically. To do so, use the
SqlCacheDepen-
dency
class, which is illustrated in Listing 23-7.
1096
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1097
Chapter 23: Caching
Listing 23-7: Working with SQL Server cache invalidation programmatically
VB
Dim myDependency As SqlCacheDependency = _
New SqlCacheDependency("Northwind", "Customers")
Response.AddCacheDependency(myDependency)
Response.Cache.SetValidUntilExpires(true)
Response.Cache.SetExpires(DateTime.Now.AddMinutes(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
C#
SqlCacheDependency myDependency = new SqlCacheDependency("Northwind", "Customers");
Response.AddCacheDependency(myDependency);
Response.Cache.SetValidUntilExpires(true);
Response.Cache.SetExpires(DateTime.Now.AddMinutes(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
You first create an instance of the
SqlCacheDependency
object, assigning it the value of the database and
the table at the same time. The
SqlCacheDependency
class takes the following parameters:
SqlCacheDependency(databaseEntryName As String, tablename As String)
You use this parameter construction if you are working with SQL Server 7.0 or with SQL Server 2000. If
you are working with SQL Server 2005, you use the following construction:

SqlCacheDependency(sqlCmd As System.Data.SqlClient.SqlCommand)
After the
SqlCacheDependency
class is in place, you add the dependency to the
Cache
object and set
some of the properties of the
Cache
object as well. You can do this either programmatically or through
the
OutputCache
directive.
Attaching SQL Server Cache Dependencies
to the Cache Object
In addition to attaching SQL Server cache dependencies to the
Request
object, you can attach them
to the
Cache
object for data that can be cached much longer. The
Cache
object is contained within the
System.Web.Caching
namespace, and it enables you to work programmatically with the caching of
any type of objects. Listing 23-8 shows a page that utilizes the
Cache
object with the
SqlDependency
object.
Listing 23-8: Using the Cache object with the SqlDependency object

VB
<
%@ Page Language="VB" %
>
<
%@ Import Namespace="System.Data"%
>
<
%@ Import Namespace="System.Data.SqlClient"%
>
1097
Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1098
Chapter 23: Caching
<
script runat="server"
>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myCustomers As DataSet
myCustomers = CType(Cache("firmCustomers"), DataSet)
If myCustomers Is Nothing Then
Dim conn As SqlConnection = _
New SqlConnection( _
ConfigurationManager.ConnectionStrings("AppConnectionString1").ConnectionString)
Dim da As SqlDataAdapter = _
New SqlDataAdapter("Select * From Customers", conn)
myCustomers = New DataSet
da.Fill(myCustomers)
Dim myDependency As SqlCacheDependency = _
New SqlCacheDependency("Northwind", "Customers")
Cache.Insert("firmCustomers", myCustomers, myDependency)

Label1.Text = "Produced from database."
Else
Label1.Text = "Produced from Cache object."
End If
GridView1.DataSource = myCustomers
GridView1.DataBind()
End Sub
<
/script
>
<
html xmlns=" />>
<
head runat="server"
>
<
title
>
Sql Cache Invalidation
<
/title
>
<
/head
>
<
body
>
<
form id="form1" runat="server"

>
<
asp:Label ID="Label1" Runat="server"
><
/asp:Label
><
br /
>
<
br /
>
<
asp:GridView ID="GridView1" Runat="server"
><
/asp:GridView
>
<
/form
>
<
/body
>
<
/html
>
C#
<
%@ Page Language="C#" %
>
<

%@ Import Namespace="System.Data" %
>
<
%@ Import Namespace="System.Data.SqlClient" %
>
<
script runat="server"
>
protected void Page_Load(object sender, System.EventArgs e)
{
DataSet myCustomers;
myCustomers = (DataSet)Cache["firmCustomers"];
if (myCustomers == null)
{
SqlConnection conn = new
1098

×