SqlDependency en una aplicación ASP.NET

En el ejemplo de esta sección se muestra cómo usar SqlDependency indirectamente aprovechando el objeto SqlCacheDependency de ASP.NET. El objeto SqlCacheDependency usa SqlDependency para escuchar notificaciones y actualizar correctamente la memoria caché.

Nota:

En el ejemplo de código se parte de que las notificaciones de consulta están habilitadas mediante la ejecución de los scripts en Habilitación de notificaciones de consultas.

Acerca de la aplicación de ejemplo

La aplicación de ejemplo usa una única página web de ASP.NET para mostrar información de producto de la base de datos AdventureWorks de SQL Server en un control GridView. Cuando se carga la página, el código escribe la hora actual en un control de Label. A continuación, define un objeto de SqlCacheDependency y establece propiedades en el objeto Cache para almacenar los datos de la memoria caché durante un máximo de tres minutos. Después, el código se conecta a la base de datos y recupera los datos. Cuando se carga la página y la aplicación se ejecuta, ASP.NET recuperará los datos de la memoria caché, lo cual se puede comprobar observando que la hora de la página no cambia. Si los datos que se supervisan cambian, ASP.NET invalida la memoria caché y vuelve a rellenar el control GridView con datos nuevos, actualizando la hora que se muestra en el control Label.

Crear la aplicación de ejemplo

Siga estos pasos para crear y ejecutar la aplicación de ejemplo:

  1. Cree un nuevo sitio web de ASP.NET.

  2. Agregue un control Label y GridView a la página Default.aspx.

  3. Abra el módulo de clase de la página y agregue las siguientes directivas:

    Option Strict On  
    Option Explicit On  
    
    Imports System.Data.SqlClient  
    
    using System.Data.SqlClient;  
    using System.Web.Caching;  
    
  4. Agregue el siguiente código en el evento Page_Load de la 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. Agregue dos métodos del asistente, GetConnectionString y GetSQL. La cadena de conexión definida usa seguridad integrada. Debe comprobar que la cuenta que usa dispone de los permisos de base de datos necesarios y que la base de datos de ejemplo, AdventureWorks, tiene habilitadas las notificaciones.

    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
    

Probar la aplicación

La aplicación almacena en caché los datos que se muestran en el formulario web y los actualiza cada tres minutos si no hay ninguna actividad. Si se produce un cambio en la base de datos, la caché se actualiza inmediatamente. Ejecute la aplicación desde Visual Studio, que carga la página en el explorador. La hora de actualización de la caché que se muestra indica cuándo se actualizó la memoria caché por última vez. Espere tres minutos y, a continuación, actualice la página, lo que hará que se produzca un evento de postback. Observe que la hora que se muestra en la página ha cambiado. Si actualiza la página en menos de tres minutos, la hora que se muestra en la página seguirá siendo la misma.

Ahora, actualice los datos de la base de datos mediante un comando UPDATE de Transact-SQL y actualice la página. La hora que se muestra ahora indica que la memoria caché se ha actualizado con los nuevos datos de la base de datos. Tenga en cuenta que aunque la memoria caché se actualiza, la hora que se muestra en la página no cambia hasta que se produce un evento de postback.

Sincronización de caché distribuida mediante dependencia de SQL

Algunas de las cachés distribuidas de terceros, como NCache, proporcionan compatibilidad para sincronizar la base de datos SQL y la caché mediante dependencias de SQL. Para obtener más información y una implementación de código fuente de ejemplo, vea Ejemplo de dependencia de SQL de caché distribuida.

Consulte también