SqlDependency in an ASP.NET application

Download ADO.NET

The example in this section shows how to use SqlDependency indirectly by using the ASP.NET SqlCacheDependency object. The SqlCacheDependency object uses a SqlDependency to listen for notifications and correctly update the cache.

Note

The sample code assumes that you have enabled query notifications by executing the scripts in Enabling query notifications.

About the sample application

The sample application uses a single ASP.NET Web page to display product information from the AdventureWorks SQL Server database in a GridView control. When the page loads, the code writes the current time to a Label control. It then defines a SqlCacheDependency object and sets properties on the Cache object to store the cache data for up to three minutes. The code then connects to the database and retrieves the data. When the page is loaded and the application is running ASP.NET will retrieve data from the cache, which you can verify by noting that the time on the page doesn't change. If the data being monitored changes, ASP.NET invalidates the cache and repopulates the GridView control with fresh data, updating the time displayed in the Label control.

Creating the sample application

Follow these steps to create and run the sample application:

  1. Create a new ASP.NET Web site.

  2. Add a Label and a GridView control to the Default.aspx page.

  3. Open the page's class module and add the following directives:

    using Microsoft.Data.SqlClient;
    using System.Web.Caching;
    
  4. Add the following code in the page's Page_Load event:

    // using Microsoft.Data.SqlClient;
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = "Cache Refresh: " +
        DateTime.Now.ToLongTimeString();
    
        // Create a dependency connection to the database.
        SqlDependency.Start(GetConnectionString());
    
        using (SqlConnection connection =
            new SqlConnection(GetConnectionString()))
        {
            using (SqlCommand command =
                new SqlCommand(GetSQL(), connection))
            {
                SqlCacheDependency dependency =
                    new SqlCacheDependency(command);
                // Refresh the cache after the number of minutes
                // listed below if a change does not occur.
                // This value could be stored in a configuration file.
                int numberOfMinutes = 3;
                DateTime expires =
                    DateTime.Now.AddMinutes(numberOfMinutes);
    
                Response.Cache.SetExpires(expires);
                Response.Cache.SetCacheability(HttpCacheability.Public);
                Response.Cache.SetValidUntilExpires(true);
    
                Response.AddCacheDependency(dependency);
    
                connection.Open();
    
                GridView1.DataSource = command.ExecuteReader();
                GridView1.DataBind();
            }
        }
    }
    
  5. Add two helper methods, GetConnectionString and GetSQL. The connection string defined uses integrated security. Verify that the account you're using has the necessary database permissions and that the sample database, AdventureWorks, has notifications enabled.

    // using Microsoft.Data.SqlClient;
    private string GetConnectionString()
    {
        // To avoid storing the connection string in your code,
        // you can retrieve it from a configuration file.
        return "Data Source=(local);Integrated Security=true;" +
          "Initial Catalog=AdventureWorks;";
    }
    private string GetSQL()
    {
        return "SELECT Production.Product.ProductID, " +
        "Production.Product.Name, " +
        "Production.Location.Name AS Location, " +
        "Production.ProductInventory.Quantity " +
        "FROM Production.Product INNER JOIN " +
        "Production.ProductInventory " +
        "ON Production.Product.ProductID = " +
        "Production.ProductInventory.ProductID " +
        "INNER JOIN Production.Location " +
        "ON Production.ProductInventory.LocationID = " +
        "Production.Location.LocationID " +
        "WHERE ( Production.ProductInventory.Quantity <= 100 ) " +
        "ORDER BY Production.ProductInventory.Quantity, " +
        "Production.Product.Name;";
    }
    

Testing the application

The application caches the data displayed on the Web form and refreshes it every three minutes if there's no activity. If a change occurs to the database, the cache is refreshed immediately. Run the application from Visual Studio, which loads the page into the browser. The cache refresh time displayed indicates when the cache was last refreshed. Wait three minutes, and then refresh the page, causing a postback event to occur. The time displayed on the page has changed. If you refresh the page in less than three minutes, the time displayed on the page will remain the same.

Now update the data in the database using a Transact-SQL UPDATE command and refresh the page. The time displayed now indicates the cache was refreshed with the new data from the database. Although the cache is updated, the time displayed on the page doesn't change until a postback event occurs.

Next steps