Using DataSource Caching


Using DataSource Caching

Instead of caching at the page or User Control level, you can cache at the level of a DataSource control. All three of the standard ASP.NET DataSource controlsthe SqlDataSource, ObjectDataSource, and XmlDataSource controlsinclude properties that enable you to cache the data that the DataSource control represents.

One advantage of using the DataSource controls when caching is that the DataSource controls can reload data automatically when the data is updated. For example, if you use a SqlDataSource control to both select and update a set of database records, then the SqlDataSource control is smart enough to reload the cached data after an update.

The DataSource controls are also smart enough to share the same data across multiple pages. For example, when using the SqlDataSource control, a unique entry is created in the Cache object for each combination of the following SqlDataSource properties: SelectCommand, SelectParameters, and ConnectionString. If these properties are identical for two SqlDataSource controls located on two different pages, then the two controls share the same cached data.

In this section, you learn how to use the SqlDataSource, ObjectDataSource, and XmlDataSource controls to cache data. You learn how to set either an absolute or sliding expiration policy. Finally, you learn how to create a cache key dependency that you can use to expire the cache programmatically.

Using an Absolute Cache Expiration Policy

When you use an absolute cache expiration policy, the data that a DataSource represents is cached in memory for a particular duration of time. Using an absolute cache expiration policy is useful when you know that your data does not change that often. For example, if you know that the records contained in a database table are modified only once a day, then there is no reason to keep grabbing the same records each and every time someone requests a web page.

Warning

When caching with the SqlDataSource control, the SqlDataSource control's DataSourceMode property must be set to the value DataSet (the default value) rather than DataReader.


The page in Listing 23.27 displays a list of movies that are cached in memory. The page uses a SqlDataSource control to cache the data.

Listing 23.27. DataSourceAbsoluteCache.aspx

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>DataSource Absolute Cache</title> </head> <body>     <form  runat="server">     <div>     <asp:GridView                  DataSource         Runat="server" />     <asp:SqlDataSource                  EnableCaching="True"         CacheDuration="3600"         SelectCommand="SELECT * FROM Movies"         ConnectionString="<%$ ConnectionStrings:Movies %>"         Runat="server" />     </div>     </form> </body> </html> 

In Listing 23.27, two properties of the SqlDataSource control related to caching are set. First, the EnableCaching property is set to the value true. Next, the CacheDuration property is set to the value 3,600 seconds (1 hour). The movies are cached in memory for a maximum of one hour. If you don't supply a value for the CacheDuration property, the default value is Infinite.

It is important to understand that there is no guarantee that the SqlDataSource control will cache data for the amount of time specified by its CacheDuration property. Behind the scenes, DataSource controls use the Cache object for caching. This object supports scavenging. When memory resources become low, the Cache object automatically removes items from the cache.

You can test whether the page in Listing 23.27 is working by opening the page and temporarily turning off your database server. You can turn off SQL Server Express by opening the SQL Configuration Manager located in the Microsoft SQL Server 2005 program group and stopping the SQL Server service (see Figure 23.11). If you refresh the page, the data is displayed even though the database server is unavailable.

Figure 23.11. The SQL Configuration Manager.


Using a Sliding Cache Expiration Policy

If you need to cache a lot of data, then it makes more sense to use a sliding expiration policy rather than an absolute expiration policy. When you use a sliding expiration policy, data remains in the cache as long as the data continues to be requested within a certain interval.

For example, imagine that you have been asked to rewrite the Amazon website with ASP.NET 2.0. The Amazon website displays information on billions of books. You couldn't cache all this book information in memory. However, if you use a sliding expiration policy, then you can cache the most frequently requested books automatically.

The page in Listing 23.28 illustrates how you can enable a sliding cache expiration policy. The cache duration is set to 15 seconds. As long as no more than 15 seconds pass before you request the page, the movies are kept cached in memory.

Listing 23.28. DataSourceSlidingCache.aspx

[View full width]

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     Sub srcMovies_Selecting(ByVal sender As Object, ByVal e As  SqlDataSourceSelectingEventArgs)         lblMessage.Text = "Selecting data from database"     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>DataSource Sliding Cache</title> </head> <body>     <form  runat="server">     <div>     <p>     <asp:Label                  EnableViewState="false"         Runat="server" />     </p>     <asp:GridView                  DataSource         Runat="server" />     <asp:SqlDataSource                  EnableCaching="True"         CacheExpirationPolicy="Sliding"         CacheDuration="15"         SelectCommand="SELECT * FROM Movies"         ConnectionString="<%$ ConnectionStrings:Movies %>"         OnSelecting="srcMovies_Selecting"         Runat="server" />     </div>     </form> </body> </html> 

Notice that the page in Listing 23.28 includes a srcMovies_Selecting() event handler. This handler is called only when the movies are retrieved from the database rather than from memory. In other words, you can use this event handler to detect when the movies are dropped from the cache (see Figure 23.12).

Figure 23.12. Using a sliding expiration policy with a DataSource control.


Caching with the ObjectDataSource Control

The ObjectDataSource control supports the same caching properties as the SqlDataSource control. You can cache the data that an ObjectDataSource control represents by setting its EnableCaching, CacheDuration, and (optionally) CacheExpirationPolicy properties.

Note

Multiple ObjectDataSource controls can share the same cached data. To share the same cache, the ObjectDataSource controls must have identical TypeName, SelectMethod, and SelectParameters properties.


For example, the page in Listing 23.29 uses an ObjectDataSource control to represent the Movies database table. The ObjectDataSource is bound to a component named Movie that includes a method named GetMovies() that returns all of the records from the Movies database table.

Listing 23.29. ShowObjectDataSourceCaching.aspx

[View full width]

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">     Sub srcMovies_Selecting(ByVal sender As Object, ByVal e As  ObjectDataSourceSelectingEventArgs)         lblMessage.Text = "Selecting data from component"     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>Show ObjectDataSource Caching</title> </head> <body>     <form  runat="server">     <div>     <asp:Label                  EnableViewState="false"         Runat="server" />     <br /><br />     <asp:GridView                  DataSource         Runat="server" />     <asp:ObjectDataSource                  EnableCaching="true"         CacheDuration="15"         TypeName="Movie"         SelectMethod="GetMovies"         OnSelecting="srcMovies_Selecting"         Runat="server" />     </div>     </form> </body> </html> 

The ObjectDataSource control in Listing 23.29 includes an event handler for its Selecting event. The event handler displays a message in a Label control. Because the Selecting event is not raised when data is retrieved from the cache, you can use this method to determine when data is retrieved from the cache or the Movie component.

The Movie component is contained in Listing 23.30.

Listing 23.30. Movie.vb

[View full width]

Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Web.Configuration Public Class Movie     Public Shared Function GetMovies() As DataTable         Dim conString As String = WebConfigurationManager.ConnectionStrings("Movies") .ConnectionString         Dim dad As New SqlDataAdapter("SELECT Title,Director FROM Movies", conString)         Dim movies As New DataTable()         dad.Fill(movies)         Return movies     End Function  End Class 

Notice that the GetMovies() method returns a DataTable. When using the ObjectDataSource control, you can cache certain types of data but not others. For example, you can cache data represented with a DataSet, DataTable, DataView, or collection. However, you cannot cache data represented by a DataReader. If you attempt to bind to a method that returns a DataReader, then an exception is thrown.

Caching with the XmlDataSource Control

Unlike the SqlDataSource and ObjectDataSource controls, the XmlDataSource control has caching enabled by default. The XmlDataSource automatically creates a file dependency on the XML file that it represents. If the XML file is modified, the XmlDataSource control automatically reloads the modified XML file.

For example, the page in Listing 23.31 contains an XmlDataSource control that represents the Movies.xml file. If you modify the Movies.xml file, then the contents of the files are automatically reloaded.

Listing 23.31. ShowXmlDataSourceCaching.aspx

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>Show XmlDataSource Caching</title> </head> <body>     <form  runat="server">     <div>     <asp:GridView                  DataSource         Runat="server" />     <asp:XmlDataSource                  DataFile="Movies.xml"         Runat="server" />     </div>     </form> </body> </html> 

Creating a DataSource Control Key Dependency

Imagine that your web application has multiple pages that display different sets of records from the Movies database table. However, you have one page that enables a user to enter a new movie. In that case, you need some method of signaling to all your DataSource controls that the Movies database table has changed.

You can create a key dependency between the DataSource controls in your application and an item in the cache. That way, if you remove the item from the cache, all the DataSource controls will reload their data.

The page in Listing 23.32 contains a SqlDataSource control that displays the contents of the Movies database table. The SqlDataSource caches its data for an infinite duration.

Listing 23.32. DataSourceKeyDependency.aspx

[View full width]

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     Sub srcMovies_Selecting(ByVal sender As Object, ByVal e As  SqlDataSourceSelectingEventArgs)         lblMessage.Text = "Selecting data from database"     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>DataSource Key Dependency</title> </head> <body>     <form  runat="server">     <div>     <p>     <asp:Label                  EnableViewState="false"         Runat="server" />     </p>     <asp:GridView                  DataSource         Runat="server" />     <asp:SqlDataSource                  EnableCaching="True"         CacheDuration="Infinite"         CacheKeyDependency="MovieKey"         SelectCommand="SELECT * FROM Movies"         ConnectionString="<%$ ConnectionStrings:Movies %>"         OnSelecting="srcMovies_Selecting"         Runat="server" />     <br /><br />     <a href="AddMovieDataSourceKeyDependency.aspx">Add Movie</a>     </div>     </form> </body> </html> 

Notice that the SqlDataSource control in Listing 23.32 includes a CacheKeyDependency property that has the value MovieKey. This property creates a dependency between the DataSource control's cached data and an item in the cache named MovieKey.

The Global.asax file in Listing 23.33 creates the initial MovieKey cache item. The value of the cache item doesn't really matter. In Listing 23.33, the MovieKey cache item is set to the current date and time.

Listing 23.33. Global.asax

<%@ Application Language="VB" %> <script runat="server">     Private Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)         Dim context As HttpContext = HttpContext.Current         context.Cache.Insert( _             "MovieKey", _             DateTime.Now, _             Nothing, _             DateTime.MaxValue, _             Cache.NoSlidingExpiration, _             CacheItemPriority.NotRemovable, _             Nothing)     End Sub </script> 

The page in Listing 23.34 contains a DetailsView control that enables you to insert a new record. Notice that the DetailsView control's ItemInserted event is handled. When you insert a new record, the MovieKey item is reinserted into the cache and every DataSource control that is dependent on this key is reloaded automatically.

Listing 23.34. AddMovieDataSourceKeyDependency.aspx

<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">     Sub dtlMovie_ItemInserted(ByVal sender As Object, ByVal e As DetailsViewInsertedEventArgs)         Cache.Insert("MovieKey", DateTime.Now)         Response.Redirect("~/DataSourceKeyDependency.aspx")     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <title>Add Movie Key Dependency</title> </head> <body>     <form  runat="server">     <div>     <h1>Add Movie</h1>     <asp:DetailsView                  DefaultMode="Insert"         DataSource         AutoGenerateRows="false"         AutoGenerateInsertButton="true"         OnItemInserted="dtlMovie_ItemInserted"         Runat="server">         <Fields>         <asp:BoundField             DataField="Title"             HeaderText="Title:" />         <asp:BoundField             DataField="Director"             HeaderText="Director:" />         </Fields>     </asp:DetailsView>     <asp:SqlDataSource                  ConnectionString="<%$ ConnectionStrings:Movies %>"         InsertCommand="INSERT Movies (Title, Director)             VALUES (@Title, @Director)"         Runat="server" />     </div>     </form> </body> </html> 




ASP. NET 2.0 Unleashed
ASP.NET 2.0 Unleashed
ISBN: 0672328232
EAN: 2147483647
Year: 2006
Pages: 276

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net