When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, January 24, 2007

Accessing and Updating Data in ASP.NET: Declaratively Caching Data

By Scott Mitchell


A Multipart Series on ASP.NET's Data Source Controls
ASP.NET 2.0 introduced a number of new Web controls designed for accessing and modifying data. These controls allow page developers to declaratively access and modify data without writing any code to perform the data access. This article is one in a series of articles on ASP.NET's data source controls.

  • Data Source Control Basics - explores the concepts and advantages of data source controls, and compares their usage in ASP.NET 2.0 to data access techniques in ASP.NET 1.x.
  • Accessing Database Data - shows how to use the SqlDataSource and AccessDataSource controls to query data from a relational database.
  • Filtering Database Data with Parameters - learn how to retrieve just a subset of database data based on hard-coded values and values from the querystring, other Web controls on the page, session variables, and so on.
  • Retrieving XML Data with XmlDataSource Control - see how to retrieve both remote and local XML data and display it in a data Web control.
  • Creating Custom Parameter Controls - learn how to create your own custom, declarative Parameter controls for use in the data source controls' parameters collections.
  • Examining the Data Source Control's Events - explore the events raised during a data source control's lifecycle.
  • Declaratively Caching Data - learn how to cache data to the data cache simply by setting a couple of data source control properties.
  • Programmatically Accessing Data using the Data Source Controls - programmatically retrieve, insert, delete, and update data using the SqlDataSource and AccessDataSource controls.
  • Inserting Data - learn how to insert data using a SqlDataSource control. Also examines how to retrieve the IDENTITY column value for the just-inserted record.
  • Deleting Data - see how to delete data using a SqlDataSource control. Also looks at how to programmatically cancel a delete.
  • Updating Basics - learn the basics of updating database data using a SqlDataSource control. Also examines using the GridView to provide a web-based editing interface.
  • Customizing the Editing Interface - see how to customize the GridView's columns to provide a customized editing interface that includes input validation and alternative user interface elements.
  • Handling Database NULL Valuese - explore how to extend the GridView's customized editing interface to handle database NULL values.
  • Using Optimistic Concurrency - see how to prevent concurrent users from overwritting one anothers changes by using concurrency control.
  • Filtering Data Using a CheckBoxList - learn how to filter data based on the end user's selections in a CheckBoxList.
  • (Subscribe to this Article Series! )

    Introduction


    The ASP.NET 2.0 data source controls provide a declarative means for accessing and working with data. Simply set a few properties of the data source control, bind it to a data Web control, and, voila, data is being retrieved and displayed without having written a single line of code!

    In addition to working with data declaratively, the data source controls can also cache data declaratively. Caching is a common technique used in data-driven applications to boost performance, and works by storing database data in memory where it can be more efficiently accessed. ASP.NET provides the data cache, which is a programmatically-accessible cache that is commonly used to store database results. See Caching in ASP.NET for more details on using the data cache and other caching options in ASP.NET.

    What's worth noting about the data source controls is that they offer declarative access to the data cache. By simply setting a few properties, the data source controls will happily store their retrieved data in the data cache. Then, the next time the data source is asked to retrieve data, they'll pull that data from the cache instead of returning to the database. In this article we'll explore how to setup a data source control so that it stores it caches its results. Read on to learn more!

    - continued -

    A Quick Primer on Caching


    Caching is a technique for improving performance by moving data from some expensive data store to one that is less so. By "expensive" I mean that there is a performance cost associated with working with the data and by "data store" I mean some location where data is stored: a database, a file, memory, and so forth. The canonical caching example is taking information from a database and storing it in an application's memory, since an application can read from its memory many orders of magnitude faster than it can read the same data from a remote database server.

    Caching carries with it some limitations. Almost always, the more efficent data store has less storage space than the slower store. That is, chances are the database holds a lot more information than can fit in the application's memory. Therefore, not all data can be cached. Moreover, when adding data to the cache, other cached information might need to be evicted from the cache in order to make room.

    Also, caching imposes a disconnect between data the application sees and the source data itself. If the source data is updated or deleted, the application working with a cached copy won't know that it's data has become stale until it returns to the original data store and determines that this, indeed, is the case. For this reason, data is typically only cached for a pre-determined duration, after which the data is automatically evicted. This places an upperbound on how long the cached data may be stale. (ASP.NET 2.0 offers SQL cache dependencies, which is a more proactive technique for determining if the cached data has become stale. This article does not explore SQL cache dependencies, but see the "Further Readings" section at the end for more information on this topic.)

    The data cache is the cache store commonly used by ASP.NET applications. It is an in-memory cache that is accessible through the Cache object. The data cache provides dictionary-like access to its contents. To add an item to the cache, specify a key for that cache item, where the key is a string. Likewise, to retrieve an item from the cache, refer to it via its key. The following code snippet shows reading and writing to the data cache:

    // C#
    Cache["key"] = ObjectToCache;  // write to the cache
    object myData = Cache["key"];  // read from the cache
    
    ' VB
    Cache("key") = ObjectToCache         ' write to the cache
    Dim myData As Object = Cache("key")  ' read from the cache
    

    Caching Data Retrieved from the Data Source Controls


    The ObjectDataSource, SqlDataSource, AccessDataSource, and XmlDataSource controls all contain properties that instruct the data source control to cache its data in the data cache. This caching occurs automatically and requires no code from us, the page developer. The key properties are:
    • EnableCaching - a Boolean value that indicates whether or not caching should be applied. Defaults to False. You will need to set this to True to instruct the data source control to employ caching.
    • CacheDuration - an Integer value that indicates the duration the data should be cached (in seconds).
    • CacheExpirationPolicy - specifies the cache expiration behavior; can be set to Absolute or Sliding. Absolute means that the cached item will be evicted CacheDuration seconds from when the item is initially inserted into the cache. Sliding means that the item will be evicted CacheDuration seconds after the last time the data is accessed from the cache. The default is Absolute.
    • CacheKeyDependency - a String value that specifies an additional item in the cache that serves as a dependency. If this value is specified, then whenever the cache item CacheKeyDependency is modified, the data source will automatically evict its data from the cache as well.
    The SqlDataSource and ObjectDataSource controls also have a SqlCacheDependency property that should be used if you are using SQL cache dependencies. Also note that while the AccessDataSource has this property, attempting to use it in will result in a NotSupportedException exception to be thrown. Also note that the data source controls will only cache data if EnableCaching is set to True and either a time-based expiry is specified via the CacheDuration property or a SQL cache dependency is specified.

    The following declarative syntax shows an AccessDataSource that is configured to support caching for an absolute duration of 30 seconds (also be sure to check out the more in-depth demos available for download at the end of this article):

    <asp:AccessDataSource ID="ProductsDataSource" runat="server" 
        DataFile="~/App_Data/Northwind.mdb"
        SelectCommand="SELECT * FROM [Products]"
        CacheDuration="30" 
        EnableCaching="True">
    </asp:AccessDataSource>
    

    When this AccessDataSource's Select method was invoked by a data Web control (such as a GridView), the AccessDataSource would first see if its data was in the data cache. If not, it would connect to the Microsoft Access database (Northwind.mdb) and issue the SelectCommand query. It would then cache the results in the data cache and return them to the requesting data Web control. Now, imagine that five seconds later another user visits the page. The data Web control will again request the AccessDataSource for its data, but this time the data will be in the cache. Therefore, the AccessDataSource will return its data to the data Web control without having to connect to the database. After 30 seconds, though, the data will be evicted from the cache and the subsequent request will go back to the database.

    A Detailed Look at How the Data Source Caches its Data


    When the Select method is invoked for a data source control that has been configured for caching, the data source control starts by checking to see if its data resides in the data cache. As mentioned earlier, the data cache's items are accessed by a string key. The key used by the data source control is a combination of its essential properties. For the SqlDataSource, this includes the value of the CacheDuration, CacheExpirationPolicy, ConnectionString, SelectCommand, and SelectParameters properties. This ensures that the cache is unique per the connection, per the SELECT query, and per the SELECT query's parameter names and values (if any).

    If the item is found in the data cache, the data source control returns the cached data and does not raise its Selecting event. As discussed in the Examining the Data Source Control's Events article, the Selecting event fires each time the data source control's Select method is invoked and data is retrieved from the underlying store.

    If the item is not found in the cache, then the data source control proceeds through its normal selecting workflow: the Selecting event fires, the underlying data store is accessed and data retrieved, and the Selected event fires. Before the data is returned, however, the data source control first adds it to the data cache, using the same key construction process discussed above.

    The following sequence diagram depicts the caching workflow for the ObjectDataSource, although the workflow is identical for the AccessDataSource, SqlDataSource, and XmlDataSource controls as well. Note how the Selecting event does not first if the item is served from the cache.

    The workflow of an object data source that uses caching.

    We can use the fact that the Selecting event only fires when the data is retrieved from the underlying data store to display information on a page of when the data was last cached. The examples available for download at the end of this article use a Label Web control that's updated with the current date and time each time the Selecting event fires, thereby showing the most recent time the cache was updated. While an end user might not care or need to see this information, it's helpful for page developers as it shows when cached data is being stored and what actions can cause the cached data to be prematurely evicted.

    Evicting Items from the Cache


    One downside of caching is stale data. While a short time-based expiry can help limit the total duration of potentially stale data, there are other actions that can be taken to forcibly evict an item from the data cache. The data source controls will automatically remove their data from the cache if the data source control's Insert, Update, or Delete methods are invoked. We've yet to explore these data modification methods available in the data source controls, but we most certainly will in a future installment. In short, these methods modify the underlying data store, as their names imply, and can be configured declaratively. When any of these methods are executed, the data source control is modifying the underlying data store, so it makes sense for the data source control to evict the cached data since it now knows that that data is stale. You can see this behavior in the examples available for download at the end of this article.

    You can also programmatically remove the data source control's cached data by using the CacheKeyDependency property. Simply set the CacheKeyDependency property to the key value of some data in the cache. Then, to remove the data source control's cached data, simply update the cache item CacheKeyDependency.

    Start by setting the data source control's CacheKeyDependency property to the name of the cache item key you want to serve as a dependency. You can choose any old name for this property:

    <asp:AccessDataSource ID="ProductsDataSource" runat="server" 
        DataFile="~/App_Data/Northwind.mdb"
        SelectCommand="SELECT * FROM [Products]"
        CacheDuration="30" 
        EnableCaching="True"
        CacheKeyDependency="ProductsDependency">
    </asp:AccessDataSource>
    

    Next, it's imperative that this item exists in the cache, otherwise the data cached by the data source control will be immediately evicted from the data cache each time its added. In the Page_Load event handler, test to see if the item exists in the cache and, if not, add it:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        'Add the Cache item, if needed
        If Cache(ProductsDataSource.CacheKeyDependency) Is Nothing Then
            Cache(ProductsDataSource.CacheKeyDependency) = DateTime.Now
        End If
    End Sub
    

    Here I assign DateTime.Now to the cache item, but you can use any value. DateTime.Now is a good choice, though, because it indicates the last time the cache item was last updated.

    To programmatically evict the data source's cached data, simply update the value of the Cache(ProductsDataSource.CacheKeyDependency) cache item, such as to the current date and time (Cache(ProductsDataSource.CacheKeyDependency) = DateTime.Now). In the download at the end of this article there's an example that includes a Button Web control that, when clicked, evicts the data from the cache by updating Cache(ProductsDataSource.CacheKeyDependency) to the current date and time. That's all there is to it!

    Conclusion


    The data source controls make accessing and working with data as easy as setting a few properties. Oftentimes, no code is required. As we saw in this article, this declarative model is also extended to caching. A data source control's data can be cached in the data cache using a time-based expiry simply by setting the EnableCaching property to True and the CacheDuration property to the duration the data should be cached (in seconds). The SqlDataSource and ObjectDataSource controls can also use SQL cache dependencies, although this topic will have to wait for a future article.

    Happy Programming!

  • By Scott Mitchell


    Futher Readings:


  • Caching for Performance
  • ASP.NET 2.0 Caching Features (includes SQL cache dependencies)
  • ASP.NET Caching: Techniques and Best Practices
  • A Video on Using Caching in ASP.NET 2.0
  • Attachments:


  • Download the code used in this article

    A Multipart Series on ASP.NET's Data Source Controls
    ASP.NET 2.0 introduced a number of new Web controls designed for accessing and modifying data. These controls allow page developers to declaratively access and modify data without writing any code to perform the data access. This article is one in a series of articles on ASP.NET's data source controls.

  • Data Source Control Basics - explores the concepts and advantages of data source controls, and compares their usage in ASP.NET 2.0 to data access techniques in ASP.NET 1.x.
  • Accessing Database Data - shows how to use the SqlDataSource and AccessDataSource controls to query data from a relational database.
  • Filtering Database Data with Parameters - learn how to retrieve just a subset of database data based on hard-coded values and values from the querystring, other Web controls on the page, session variables, and so on.
  • Retrieving XML Data with XmlDataSource Control - see how to retrieve both remote and local XML data and display it in a data Web control.
  • Creating Custom Parameter Controls - learn how to create your own custom, declarative Parameter controls for use in the data source controls' parameters collections.
  • Examining the Data Source Control's Events - explore the events raised during a data source control's lifecycle.
  • Declaratively Caching Data - learn how to cache data to the data cache simply by setting a couple of data source control properties.
  • Programmatically Accessing Data using the Data Source Controls - programmatically retrieve, insert, delete, and update data using the SqlDataSource and AccessDataSource controls.
  • Inserting Data - learn how to insert data using a SqlDataSource control. Also examines how to retrieve the IDENTITY column value for the just-inserted record.
  • Deleting Data - see how to delete data using a SqlDataSource control. Also looks at how to programmatically cancel a delete.
  • Updating Basics - learn the basics of updating database data using a SqlDataSource control. Also examines using the GridView to provide a web-based editing interface.
  • Customizing the Editing Interface - see how to customize the GridView's columns to provide a customized editing interface that includes input validation and alternative user interface elements.
  • Handling Database NULL Valuese - explore how to extend the GridView's customized editing interface to handle database NULL values.
  • Using Optimistic Concurrency - see how to prevent concurrent users from overwritting one anothers changes by using concurrency control.
  • Filtering Data Using a CheckBoxList - learn how to filter data based on the end user's selections in a CheckBoxList.
  • (Subscribe to this Article Series! )



  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article