SqlDependency em um aplicativo ASP.NET

O exemplo nesta seção mostra como usar SqlDependency indiretamente, utilizando o objeto ASP.NET SqlCacheDependency. O objeto SqlCacheDependency usa um SqlDependency para escutar notificações e atualizar corretamente o cache.

Observação

O código de exemplo pressupõe que você habilitou notificações de consulta executando os scripts em Habilitar as notificações de consulta.

Sobre o aplicativo de exemplo

O aplicativo de exemplo usa uma página da Web ASP.NET para exibir informações sobre o produto no banco de dados do SQL Server AdventureWorks em um controle GridView. Quando a página é carregada, o código grava a hora atual em um controle Label. Ele define um objeto SqlCacheDependency e as propriedades no objeto Cache para armazenar os dados do cache por até três minutos. O código se conecta ao banco de dados e recupera os dados. Quando a página é carregada e o aplicativo está em execução, o ASP.NET recuperará os dados do cache, que você pode verificar observando que a hora na página não é alterada. Se os dados que estão sendo monitorados forem alterados, o ASP.NET invalidará o cache e preencherá novamente o controle GridView com os dados atualizados, atualizando a hora exibida no controle Label.

Criar o aplicativo de exemplo

Siga estas etapas para criar e executar o aplicativo de exemplo:

  1. Criar um site do ASP.NET.

  2. Adicione um Label e um controle GridView à página Default.aspx.

  3. Abra o módulo de classe da página e adicione as seguintes diretivas:

    Option Strict On  
    Option Explicit On  
    
    Imports System.Data.SqlClient  
    
    using System.Data.SqlClient;  
    using System.Web.Caching;  
    
  4. Adicione o seguinte código no evento Page_Load da página:

    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. Adicione dois métodos auxiliares, GetConnectionString e GetSQL. A cadeia de conexão definida usa segurança integrada. Você precisará verificar se a conta que está usando tem as permissões de banco de dados necessárias e se o banco de dados de exemplo, AdventureWorks, tem notificações habilitadas.

    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
    

Testando o aplicativo

O aplicativo armazenará em cache os dados exibidos no formulário da Web e os atualizará a cada três minutos se não houver atividade. Se ocorrer uma alteração no banco de dados, o cache será atualizado imediatamente. Execute o aplicativo no Visual Studio, que carrega a página para o navegador. O tempo de atualização do cache exibido indica quando o cache foi atualizado pela última vez. Aguarde três minutos e atualize a página, fazendo ocorrer um evento de postback. Observe que a hora exibida na página foi alterada. Se você atualizar a página em menos de três minutos, a hora exibida na página permanecerá a mesma.

Agora atualize os dados no banco de dados, usando um comando UPDATE Transact-SQL e atualize a página. A hora exibida agora indica que o cache foi atualizado com os novos dados do banco de dados. Observe que, embora o cache seja atualizado, a hora exibida na página não é alterada até que ocorra um evento de postback.

Sincronização de cache distribuído usando a Dependência do SQL

Alguns dos caches distribuídos de terceiros, como o NCache, dão suporte para sincronizar o banco de dados SQL e o cache usando a Dependência de SQL. Para obter mais informações e um exemplo de implementação de código-fonte, consulte exemplo de dependência de SQL de cache distribuído.

Confira também