SqlDependency в приложении ASP.NET

В приведенном в этом разделе примере показано, как применять SqlDependency косвенно, используя объект SqlCacheDependency ASP.NET. Объект SqlCacheDependency использует SqlDependency для прослушивания уведомлений и корректного обновления кэша.

Примечание.

В примере кода предполагается, что вы включили уведомления о запросах, выполнив скрипты в включении уведомлений о запросах.

О примере приложения

В примере приложения используется одна веб-страница ASP.NET для вывода сведений о продуктах из базы данных AdventureWorks SQL Server в элемент управления GridView. При загрузке страницы код записывает текущее время в элемент управления Label. Затем он определяет объект SqlCacheDependency и задает свойства объекта Cache для сохранения данных кэша до трех минут. Затем код подключается к базе данных и получает данные. При загрузке страницы и работе приложения ASP.NET будет получать данные из кэша, которые можно проверить, отметив, что время на странице не меняется. Если наблюдаемые данные изменяются, ASP.NET делает недействительным кэш и повторно заполняет элемент управления GridView новыми данными, обновляя время в элементе управления Label.

Создание примера приложения

Чтобы создать и запустить пример приложения, выполните следующие действия:

  1. Создание нового веб-сайта ASP.NET.

  2. Добавьте Label и элемент управления GridView на страницу Default.aspx.

  3. Откройте модуль класса страницы и добавьте следующие директивы:

    Option Strict On  
    Option Explicit On  
    
    Imports System.Data.SqlClient  
    
    using System.Data.SqlClient;  
    using System.Web.Caching;  
    
  4. Добавьте следующий код в событие Page_Load страницы:

    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();
            }
        }
    }
    
    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
    
  5. Добавьте два вспомогательных метода: GetConnectionString и GetSQL. В определенной строке соединения используются интегрированные средства безопасности. Необходимо будет убедиться, что используемая учетная запись обладает необходимыми разрешениями для базы данных, а в образце базы данных AdventureWorks включены уведомления.

    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;";
    }
    
    Private Function GetConnectionString() As String
        ' 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;"
    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
    

Тестирование приложения

Приложение кэширует данные, отображаемые в веб-форме, и обновляет их каждые три минуты, если нет действий. Если в базе данных происходит изменение, кэш обновляется немедленно. Запустите приложение из Visual Studio, чтобы загрузить страницу в браузер. Отображаемое время обновления кэша указывает, когда кэш был обновлен последний раз. Подождите три минуты, а затем обновите страницу, в результате чего произойдет событие обратной передачи. Обратите внимание, что время, отображаемое на странице, изменилось. Если обновить страницу меньше чем через три минуты, время, отображаемое на странице, останется прежним.

Теперь обновите данные в базе данных, используя команду Transact-SQL UPDATE, и обновите страницу. Отображаемое время теперь указывает, что кэш был обновлен с учетом новых данных из базы данных. Обратите внимание, что хотя кэш обновляется, время на странице не изменяется, пока не произойдет событие обратной передачи.

Синхронизация распределенного кэша с помощью зависимостей SQL

Некоторые сторонние распределенные кэши, такие как NCache , обеспечивают поддержку синхронизации базы данных SQL и кэша с помощью зависимостей SQL. Дополнительные сведения и пример реализации исходного кода см . в примере зависимостей SQL распределенного кэша.

См. также