ASP.NET 应用程序中的 SqlDependency (ADO.NET)

更新:November 2007

本节中的示例演示如果通过利用 ASP.NET SqlCacheDependency 对象间接使用 SqlDependencySqlCacheDependency 对象使用 SqlDependency 来侦听通知和正确更新缓存。

说明:

示例代码假定已通过执行启用查询通知 (ADO.NET)中的脚本启用了查询通知。

关于示例应用程序

示例应用程序使用单个 ASP.NET 网页在 GridView 控件中显示 AdventureWorks SQL Server 数据库中的产品信息。加载页面时,代码将当前时间写入 Label 控件。然后,它定义一个 SqlCacheDependency 对象并设置 Cache 对象的属性,以存储最多三分钟的缓存数据。然后,代码连接到数据库并检索数据。加载页面后且应用程序运行时,ASP.NET 将从缓存中检索数据,这可以通过观察页面上的时间不改变来加以验证。如果监视的数据发生更改,ASP.NET 将令缓存失效并用新数据重新填充 GridView 控件,更新 Label 控件中显示的时间。

创建示例应用程序

请执行下面的步骤来创建并运行示例应用程序:

  1. 创建一个新的 ASP.NET 网站。

  2. 向 Default.aspx 页面添加一个 Label 和一个 GridView 控件。

  3. 打开该页面的类模块并添加下面的指令:

    Option Strict On
    Option Explicit On
    
    Imports System.Data.SqlClient
    using System.Data.SqlClient;
    using System.Web.Caching;
    
  4. 在该页面的 Page_Load 事件中添加下面的代码:

    Protected Sub Page_Load(ByVal sender As Object, _
       ByVal e As System.EventArgs) Handles Me.Load
    
        Label1.Text = "Cache Refresh: " & _
           Date.Now.ToLongTimeString()
    
        ' Create a dependency connection to the database
        SqlDependency.Start(GetConnectionString())
    
        Using connection As New SqlConnection(GetConnectionString())
            Using command As New SqlCommand(GetSQL(), connection)
                Dim dependency As 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.
                Dim numberOfMinutes As Integer = 3
                Dim expires As Date = _
                    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()
            End Using
        End Using
    End Sub
    
    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. 添加两个帮助器方法 GetConnectionString 和 GetSQL。已定义的连接字符串使用集成安全性。您将需要验证所使用的帐户是否具有必要的数据库权限,并且示例数据库 AdventureWorks 是否启用了通知。有关更多信息,请参见使用查询通知时的特别注意事项 (ADO.NET)

    Private Function GetConnectionString() As String
        ' To avoid storing the connection string in your code,
        ' you can retrive it from a configuration file.
    
        Return "Data Source=(local);Integrated Security=true;" & _
         "Initial Catalog=AdventureWorks;"
    End Function
    
    Private Function GetSQL() As String
        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;"
    End Function
    
    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;";
    }
    

测试应用程序

如果没有活动,应用程序将会缓存 Web 窗体上显示的数据并每隔三分钟刷新一次。如果对数据库发生了更改,则立即刷新缓存。从 Visual Studio 中运行应用程序,将页面加载到浏览器中。显示的缓存刷新时间指示最后刷新缓存的时间。等待三分钟,然后刷新页面,使回发事件发生。请注意,页面上显示的时间已发生改变。如果您在三分钟之内刷新页面,页面上显示的时间将保持不变。

现在使用 Transact-SQL UPDATE 命令更新数据库中的数据并刷新页面。此时显示的时间指示已用数据库中的新数据刷新了缓存。请注意,虽然已更新缓存,但页面上显示的时间在回发事件发生之前仍将保持不变。

请参见

其他资源

SQL Server 中的查询通知 (ADO.NET)