ASP.NET アプリケーションでの SqlDependency

ここでは、ASP.NET の SqlDependency オブジェクトを使用して、SqlCacheDependency を間接的に使用する方法の例を示します。 SqlCacheDependency オブジェクトでは SqlDependency を使用して通知をリッスンし、キャッシュを適切に更新します。

Note

このサンプル コードを実行するには、「クエリ通知の有効化」のスクリプトを実行してクエリ通知を有効にしておく必要があります。

サンプル アプリケーションについて

このサンプル アプリケーションでは、1 つの ASP.NET Web ページを使用して、SQL Server データベースである AdventureWorks に格納されている製品情報を GridView コントロールに表示します。 ページが読み込まれる際に、コードによって Label コントロールに現在の時刻が書き込まれます。 次に、SqlCacheDependency オブジェクトが定義され、最大 3 分間キャッシュ データが格納されるように Cache オブジェクトのプロパティが設定されます。 その後、データベースに接続され、データが取得されます。 ページが読み込まれ、アプリケーションが実行されると、ASP.NET によって、データがキャッシュから取得されます。これは、ページ上の時刻が変更されないことで確認できます。 監視しているデータが変化すると、ASP.NET によりキャッシュが無効化され、GridView コントロールに最新データが再入力されることで、Label コントロールに表示される時刻が更新されます。

サンプル アプリケーションの作成

サンプル アプリケーションを作成して実行するには、次の手順に従います。

  1. 新しい ASP.NET Web サイトを作成します。

  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 という 2 つのヘルパー メソッドを追加します。 定義される接続文字列は、統合セキュリティを利用します。 使用しているアカウントが、必要とされるデータベースへのアクセス許可を持っており、サンプル データベースの 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
    

アプリケーションのテスト

このアプリケーションは Web フォームに表示されるデータをキャッシングし、操作が行われなければ 3 分ごとにデータを更新します。 データベースに変更があれば、キャッシュは直ちに更新されます。 Visual Studio からアプリケーションを実行すると、ブラウザーにページが読み込まれます。 表示されるキャッシュ更新時刻は、最後にキャッシュが更新された時刻を示します。 3 分間の待機後、ページを更新すると、ポストバック イベントが発生します。 ページに表示される時刻が変更されることに注意してください。 3 分経過する前にページを更新した場合、ページに表示される時刻は変わりません。

次に、Transact-SQL の UPDATE コマンドを使用して、データベースのデータを更新し、ページを更新します。 表示される時刻を見ると、データベースの新しいデータを使ってキャッシュが更新されたことがわかります。 キャッシュは更新されますが、ページに表示される時刻はポストバック イベントが発生するまで変更されないことに注意してください。

SQL の依存関係を使用した分散キャッシュの同期

NCache などの一部のサードパーティの分散キャッシュでは、SQL の依存関係を使用した SQL データベースとキャッシュの同期がサポートされています。 詳細とソース コード実装の例については、分散キャッシュの SQL の依存関係のサンプルに関するページを参照してください。

関連項目