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

本节中的示例演示如果通过利用 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 是否启用了通知。 有关更多信息,请参见Special Considerations When Using Query Notifications

    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)