ASP.NET アプリケーションでの SqlDependency (ADO.NET)
ここでは、ASP.NET の SqlCacheDependency オブジェクトを使用して、SqlDependency を間接的に使用する方法の例を示します。 SqlCacheDependency オブジェクトでは SqlDependency を使用して通知をリッスンし、キャッシュを適切に更新します。
メモ |
---|
このサンプル コードを実行するには、「クエリ通知の有効化 (ADO.NET)」のスクリプトを実行してクエリ通知を有効にしておく必要があります。 |
サンプル アプリケーションについて
このサンプル アプリケーションでは、1 つの ASP.NET Web ページを使用して、SQL Server データベースである AdventureWorks に格納されている製品情報を GridView コントロールに表示します。 ページが読み込まれる際に、Label コントロールに現在の時刻が入力されます。 次に、SqlCacheDependency オブジェクトを定義し、最長 3 分間キャッシュ データを格納するように Cache オブジェクトのプロパティを設定します。 その後、データベースに接続し、データを取得します。 ページが読み込まれ、アプリケーションが実行されると、ASP.NET ではキャッシュからデータが取得されます。これは、ページ上の時刻が変更されないことで確認できます。 監視しているデータが変化すると、ASP.NET によりキャッシュが無効化され、GridView コントロールに最新データが再入力されることで、Label コントロールに表示される時刻が更新されます。
サンプル アプリケーションの作成
サンプル アプリケーションを作成して実行するには、次の手順に従います。
新しい ASP.NET Web サイトを作成します。
ページのクラス モジュールを開き、次のディレクティブを追加します。
Option Strict On Option Explicit On Imports System.Data.SqlClient using System.Data.SqlClient; using System.Web.Caching;
ページの 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(); } } }
GetConnectionString および GetSQL という 2 つのヘルパー メソッドを追加します。 定義される接続文字列は、統合セキュリティを利用します。 使用しているアカウントが、必要とされるデータベースへのアクセス許可を持っており、サンプル データベースの 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 フォームに表示されるデータをキャッシングし、操作が行われなければ 3 分ごとにデータを更新します。 データベースに変化があれば、キャッシュは直ちに更新されます。 Visual Studio からアプリケーションを実行すると、ブラウザーにページが読み込まれます。 表示されるキャッシュ更新時刻は、最後にキャッシュが更新された時刻を示します。 3 分間の待機後、ページを更新し、ポストバック イベントが発生します。 ページに表示される時刻が変更されることに注意してください。 3 分経過する前にページを更新した場合は、ページに表示される時刻は変わりません。
次に、Transact-SQL の UPDATE コマンドを使用して、データベースのデータを更新し、ページを更新します。 表示される時刻を見ると、データベースの新しいデータを使ってキャッシュが更新されたことがわかります。 キャッシュは更新されますが、ページに表示される時刻はポストバック イベントが発生するまで変更されないことに注意してください。