ObjectDataSource でデータをキャッシュする (C#)

作成者: Scott Mitchell

PDF のダウンロード

キャッシュとは、低速 Web アプリケーションと高速 Web アプリケーションの違いを意味することがあります。 このチュートリアルは、ASP.NET でのキャッシュについて詳しく説明する 4 つのチュートリアルのうちの 1 つ目です。 キャッシュの主な概念と、ObjectDataSource コントロールを使用してプレゼンテーション レイヤーにキャッシュを適用する方法について説明します。

はじめに

コンピューター サイエンスでは、キャッシュとは、取得にコストがかかるデータや情報を取得し、迅速にアクセスできる場所に格納するプロセスです。 データ ドリブン アプリケーションの場合、通常、アプリケーションの実行時間の大部分が、大規模で複雑なクエリで消費されます。 このようなアプリケーションのパフォーマンスは、多くの場合、コストの高いデータベース クエリの結果をアプリケーションのメモリに格納することで改善できます。

ASP.NET 2.0 には、さまざまなキャッシュ オプションが用意されています。 Web ページ全体またはユーザー コントロールのレンダリングされたマークアップは、出力キャッシュを使用してキャッシュできます。 ObjectDataSource および SqlDataSource コントロールにはキャッシュ機能も用意されているため、コントロール レベルでデータをキャッシュできます。 また、ASP.NET のデータ キャッシュには、ページ開発者がプログラムでオブジェクトをキャッシュできるようにする豊富なキャッシュ API が用意されています。 このチュートリアルと次の 3 つのチュートリアルでは、ObjectDataSource のキャッシュ機能とデータ キャッシュの使用について説明します。 また、起動時にアプリケーション全体のデータをキャッシュする方法と、SQL キャッシュの依存関係を使用してキャッシュされたデータを最新の状態に保つ方法についても説明します。 これらのチュートリアルでは、出力キャッシュについては説明しません。 出力キャッシュの詳細については、「ASP.NET 2.0 の出力キャッシュ」を参照してください。

キャッシュは、データ アクセス層からプレゼンテーション層まで、アーキテクチャ内の任意の場所で適用できます。 このチュートリアルでは、ObjectDataSource コントロールを使用してプレゼンテーション レイヤーにキャッシュを適用する方法について説明します。 次のチュートリアルでは、ビジネス ロジック レイヤーでのデータのキャッシュについて説明します。

キャッシュの主要な概念

キャッシュを使用すると、生成にコストがかかるデータを取得し、より効率的にアクセスできる場所にコピーを格納することで、アプリケーションの全体的なパフォーマンスとスケーラビリティを大幅に向上させることができます。 キャッシュは実際の基になるデータのコピーを保持するだけなので、基になるデータが変更されると、キャッシュが古くなったり、陳腐化したりする可能性があります。 これに対処するために、ページ開発者は、次のいずれかを使用してキャッシュからキャッシュ項目を削除する基準を指定できます。

  • 時間ベースの条件 絶対期間またはスライディング期間の間、項目をキャッシュに追加できます。 例えば、ページ開発者が、仮に60秒という期間を示すとしましょう。 絶対期間では、キャッシュされた項目は、アクセスの頻度に関係なく、キャッシュに追加されてから 60 秒後に削除されます。 スライディング期間では、キャッシュされた項目は最後のアクセスから 60 秒後に削除されます。
  • 依存関係ベースの条件 項目をキャッシュに追加する際に、依存関係を関連付けることができます。 項目の依存関係が変更されると、項目はキャッシュから削除されます。 依存関係には、ファイル、別のキャッシュ項目、またはその 2 つの組み合わせがあります。 ASP.NET 2.0 では、SQL キャッシュの依存関係も使用できます。これにより、開発者はキャッシュに項目を追加し、基になるデータベース データが変更されたときにその項目を削除できます。 SQL キャッシュの依存関係については、今後の「SQL キャッシュ依存関係の使用」に関するチュートリアルで確認します。

指定された削除条件に関係なく、時間ベースまたは依存関係ベースの条件が満たされる前に、キャッシュ内の項目が削除されることがあります。 キャッシュが容量に達した場合は、新しい項目を追加する前に既存の項目を削除する必要があります。 そのため、キャッシュされたデータをプログラムで扱う場合は、キャッシュされたデータが存在しない可能性を常に想定することが重要です。 キャッシュからプログラムでデータにアクセスする際に使用するパターンについては、次回のチュートリアル「アーキテクチャでのデータのキャッシュ」で説明します。

キャッシュは、アプリケーションからより高いパフォーマンスを引き出すための経済的な手段を提供します。 スティーブン・スミスが「ASP.NET キャッシュ: テクニックとベスト プラクティス」の記事で説明しています。

キャッシュは、多くの時間と分析を必要とせずに十分なパフォーマンスを得るための優れた方法です。 メモリは安価であるため、コードやデータベースを最適化するために 1 日または 1 週間を費やす代わりに、出力を 30 秒間キャッシュすることで必要なパフォーマンスを得ることができるのであれば、(30 秒前のデータでも問題ないと仮定して) キャッシュ ソリューションを実行し、次に進みます。 設計の不備はいつかの時点で問題になるでしょうから、もちろん、アプリケーションを正しく設計するよう努力すべきです。 しかし、今すぐ必要十分なパフォーマンスを得る必要がある場合は、キャッシュが優れた [アプローチ] になり、後日アプリケーションをリファクタリングする時間を稼ぐことができます。

キャッシュによってパフォーマンスが大幅に向上する可能性はありますが、リアルタイムで頻繁に更新されるデータを使用するアプリケーションや、短期間の古いデータでさえ許容できないアプリケーションなどの、すべての状況に適用できるわけではありません。 ただし、ほとんどのアプリケーションでは、キャッシュを使用する必要があります。 ASP.NET 2.0 でのキャッシュの詳細については、「ASP.NET 2.0 クイックスタート チュートリアル」の「パフォーマンスのためのキャッシュ」セクションを参照してください。

手順 1: キャッシュ Web ページを作成する

ObjectDataSource のキャッシュ機能について説明を始める前に、まず、このチュートリアルと次の 3 つのチュートリアルで必要となる ASP.NET ページを 当社の Web サイト プロジェクトに作成しましょう。 まず、Caching という名前の新しいフォルダーを追加します。 次に、次の ASP.NET ページをそのフォルダーに追加し、各ページを Site.master マスター ページに関連付けます。

  • Default.aspx
  • ObjectDataSource.aspx
  • FromTheArchitecture.aspx
  • AtApplicationStartup.aspx
  • SqlCacheDependencies.aspx

Add the ASP.NET Pages for the Caching-Related Tutorials

図 1: キャッシュ関連のチュートリアルのための ASP.NET ページを追加します

他のフォルダーと同様に、Caching フォルダーの Default.aspx のセクションにチュートリアルが一覧表示されます。 SectionLevelTutorialListing.ascx ユーザー コントロールではこの機能が提供されていることを思い出してください。 そのため、このユーザー コントロールをソリューション エクスプローラーからページのデザイン ビューにドラッグして Default.aspx に追加します。

Figure 2: Add the SectionLevelTutorialListing.ascx User Control to Default.aspx

図 2: SectionLevelTutorialListing.ascx ユーザー コントロールを Default.aspx に追加します (クリックしてフルサイズの画像を表示します)

最後に、これらのページをエントリとして Web.sitemap ファイルに追加します。 具体的には、[バイナリ データ <siteMapNode> で動作] の後に次のマークアップを追加します。

<siteMapNode title="Caching" url="~/Caching/Default.aspx" 
    description="Learn how to use the caching features of ASP.NET 2.0.">
    <siteMapNode url="~/Caching/ObjectDataSource.aspx" 
        title="ObjectDataSource Caching" 
        description="Explore how to cache data directly from the 
            ObjectDataSource control." />
    <siteMapNode url="~/Caching/FromTheArchitecture.aspx" 
        title="Caching in the Architecture" 
        description="See how to cache data from within the 
            architecture." />
    <siteMapNode url="~/Caching/AtApplicationStartup.aspx" 
        title="Caching Data at Application Startup" 
        description="Learn how to cache expensive or infrequently-changing 
            queries at the start of the application." />
    <siteMapNode url="~/Caching/SqlCacheDependencies.aspx" 
        title="Using SQL Cache Dependencies" 
        description="Examine how to have data automatically expire from the 
            cache when its underlying database data is modified." />
</siteMapNode>

Web.sitemap を更新した後、ブラウザーでチュートリアル Web サイトの表示を確認してみましょう。 左側のメニューに、キャッシュ チュートリアルの項目が含まれるようになりました。

The Site Map Now Includes Entries for the Caching Tutorials

図 3: サイト マップにキャッシュ チュートリアルのエントリが含まれるようになりました

手順 2: Web ページに製品の一覧を表示する

このチュートリアルでは、ObjectDataSource コントロールの組み込みキャッシュ機能を使用する方法について説明します。 しかし、これらの機能を確認する前に、まず作業するためのページが必要です。 GridView を使用して、ObjectDataSource によって ProductsBLL クラスから取得された製品情報を一覧表示する Web ページを作成してみましょう。

まず、Caching フォルダーの ObjectDataSource.aspx ページを開きます。 GridView をツールボックスから Designer にドラッグし、その ID プロパティを Products に設定し、スマート タグから "ProductsDataSource" という名前の新しい ObjectDataSource コントロールにバインドすることを選択します。 ProductsBLL クラスで動作するように ObjectDataSource を構成します。

Configure the ObjectDataSource to Use the ProductsBLL Class

図 4: クラスを使用するように ObjectDataSource を構成します ProductsBLL (フルサイズの画像を表示する をクリックします)

このページでは、編集可能な GridView を作成して、ObjectDataSource にキャッシュされたデータが GridView インターフェイスを介して変更された場合の動作を確認できるようにします。 [選択] タブのドロップダウン リストは既定の GetProducts() に設定したままにしますが、[更新] タブで選択した項目を、入力パラメーターとして productNameunitPriceproductID を受け入れる UpdateProduct オーバーロードに変更します。

Set the UPDATE Tab s Drop-Down List to the Appropriate UpdateProduct Overload

図 5: [更新] タブのドロップダウン リストを適切な UpdateProduct オーバーロードに設定します (クリックしてフルサイズの画像を表示します)

最後に、[挿入] タブと [削除] タブのドロップダウン リストを [なし] に設定し、[完了] をクリックします。 データ ソースの構成ウィザードが完了すると、Visual Studio によって ObjectDataSource の OldValuesParameterFormatString プロパティが original_{0} に設定されます。 「データの挿入、更新、削除の概要」チュートリアルで説明したように、更新ワークフローをエラーなく続行するには、このプロパティを宣言構文から削除するか、既定値 {0} に戻す必要があります。

さらに、ウィザードの完了時に、Visual Studio によって各製品データ フィールドのフィールドが GridView に追加されます。 ProductNameCategoryNameUnitPrice を除くすべての BoundField を削除します。 次に、これらの各BoundField の HeaderText プロパティをそれぞれ Product、Category、Price に更新します。 ProductName フィールドは必須であるため、BoundField を TemplateField に変換し、RequiredFieldValidator を EditItemTemplate に追加します。 同様に、UnitPrice BoundField を TemplateField に変換し、CompareValidator を追加して、ユーザーが入力した値が 0 以上の有効な通貨値であることを確認します。 これらの変更に加えて、UnitPrice 値の右揃えや、読み取り専用および編集インターフェイスでの UnitPrice テキストの書式設定の指定など、外見上の変更を自由に実行できます。

GridView のスマート タグの [編集を有効にする] チェック ボックスをオンにして、GridView を編集可能にします。 [ページングを有効にする] チェック ボックスと [並べ替えを有効にする] チェック ボックスもオンにします。

Note

GridView の編集インターフェイスをカスタマイズする方法のレビューが必要ですか? その場合は、「データ変更インターフェイスのカスタマイズ」チュートリアルを参照してください。

Enable GridView Support for Editing, Sorting, and Paging

図 6: GridView の編集、並べ替え、ページングのサポートを有効にします (クリックしてフルサイズの画像を表示します)

これらの GridView の変更を行った後、GridView と ObjectDataSource の宣言型マークアップは次のようになります。

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
    AllowPaging="True" AllowSorting="True">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
            <EditItemTemplate>
                <asp:TextBox ID="ProductName" runat="server" 
                    Text='<%# Bind("ProductName") %>'></asp:TextBox>
                <asp:RequiredFieldValidator 
                    ID="RequiredFieldValidator1" Display="Dynamic" 
                    ControlToValidate="ProductName" SetFocusOnError="True"
                    ErrorMessage="You must provide a name for the product."
                    runat="server">*</asp:RequiredFieldValidator>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" 
                    Text='<%# Bind("ProductName") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
            <EditItemTemplate>
                $<asp:TextBox ID="UnitPrice" runat="server" Columns="8" 
                    Text='<%# Bind("UnitPrice", "{0:N2}") %>'></asp:TextBox>
                <asp:CompareValidator ID="CompareValidator1"
                    ControlToValidate="UnitPrice" Display="Dynamic" 
                    ErrorMessage="You must enter a valid currency value with no 
                        currency symbols. Also, the value must be greater than 
                        or equal to zero."
                    Operator="GreaterThanEqual" SetFocusOnError="True" 
                    Type="Currency" runat="server" 
                    ValueToCompare="0">*</asp:CompareValidator>
            </EditItemTemplate>
            <ItemStyle HorizontalAlign="Right" />
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" 
                    Text='<%# Bind("UnitPrice", "{0:c}") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="{0}" SelectMethod="GetProducts" 
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

図 7 に示すように、編集可能な GridView には、データベース内の各製品の名前、カテゴリ、価格が一覧表示されます。 少し時間を取って、結果を並べ替え、ページをスクロールし、レコードを編集して、ページの機能をお試しください。

Each Product s Name, Category, and Price is Listed in a Sortable, Pageable, Editable GridView

図 7: 各製品名、カテゴリ、価格が、並べ替え可能、ページング可能、編集可能な GridView に表示されています (クリックしてフルサイズの画像を表示します)

手順 3: ObjectDataSource がデータを要求するタイミングを調べる

Products GridView は、ProductsDataSource ObjectDataSource の Select メソッドを呼び出して、表示するデータを取得します。 この ObjectDataSource は、ビジネス ロジック レイヤーの ProductsBLL クラスのインスタンスを作成し、その GetProducts() メソッドを呼び出します。これにより、データ アクセス層の ProductsTableAdapterGetProducts() メソッドが呼び出されます。 DAL メソッドは Northwind データベースに接続し、構成された SELECT クエリを発行します。 このデータは DAL に返され、NorthwindDataTable にパッケージ化されます。 DataTable オブジェクトは BLL に返され、BLL はそれを ObjectDataSource に返し、ObjectDataSource はそれを GridView に返します。 その後、GridView は DataTable 内の各 DataRow に対して GridViewRow オブジェクトを作成し、最終的に各 GridViewRow がクライアントに返され、訪問者のブラウザーに表示される HTML にレンダリングされます。

この一連のイベントは、GridView が基になるデータにバインドされる必要があるたびに発生します。 これは、ページが最初にアクセスされたとき、データのあるページから別のページに移動するとき、GridView を並べ替えるとき、または組み込みの編集または削除インターフェイスを使用して GridView のデータを変更するときに発生します。 GridView のビュー状態が無効になっている場合、GridView は各ポストバックでも再バインドされます。 DataBind() メソッドを呼び出して、GridView をデータに明示的に再バインドすることもできます。

データベースからデータを取得する頻度を十分に理解するために、データが再取得されるタイミングを示すメッセージを表示してみましょう。 "ODSEvents" という名前の GridView の上に Web ラベル コントロールを追加します。 Text プロパティをクリアし、EnableViewState プロパティを false に設定します。 ラベルの下に Web ボタン コントロールを追加し、その Text プロパティを Postback に設定します。

Add a Label and Button to the Page Above the GridView

図 8: GridView の上のページにラベルとボタンを追加します (クリックするとフルサイズの画像が表示されます)

データ アクセス ワークフロー中、ObjectDataSource の Selecting イベントは、基になるオブジェクトが作成され、構成されたメソッドが呼び出される前に発生します。 このイベントのイベント ハンドラーを作成し、次のコードを追加します。

protected void ProductsDataSource_Selecting(object sender, 
    ObjectDataSourceSelectingEventArgs e)
{
    ODSEvents.Text = "-- Selecting event fired";
}

ObjectDataSource がデータのアーキテクチャに対して要求を行うたびに、ラベルに "Selecting イベント発生" というテキストが表示されます。

ブラウザーでこのページにアクセスします。 ページに初めてアクセスすると、"Selecting イベント発生" テキストが表示されます。 [ポストバック] ボタンをクリックすると、テキストが消えます (GridView の EnableViewState プロパティが既定値 true に設定されている場合)。 これは、GridView がポストバック時にビュー状態から再構築されるため、ObjectDataSource にデータを渡さないためです。 ただし、データの並べ替え、ページング、または編集を行うと、GridView がデータ ソースに再バインドされるため、"Selecting イベント発生" テキストが再び表示されます。

Whenever the GridView is Rebound to its Data Source, Selecting event fired is Displayed

図 9: GridView がデータ ソースに再バインドされるたびに、"Selecting イベント発生" テキストが表示されます (クリックするとフルサイズの画像が表示されます)

Clicking the Postback Button Causes the GridView to be Reconstructed from its View State

図 10: [ポストバック] ボタンをクリックすると、GridView がビュー状態から再構築されます (クリックするとフルサイズの画像が表示されます)

データがページングされる、または並べ替えられるたびに、データベース データを取得するのは無駄に思えるかもしれません。 結局のところ、既定のページングを使用しているため、ObjectDataSource は最初のページを表示するときにすべてのレコードを取得しています。 GridView で並べ替えとページングのサポートが提供されていない場合でも、ユーザーが最初にページにアクセスするたびに (およびビュー状態が無効になっている場合はポストバックごとに) データベースからデータを取得する必要があります。 ただし、GridView がすべてのユーザーに同じデータを表示している場合、これらの追加のデータベース要求は不要です。 GetProducts() メソッドから返された結果をキャッシュし、キャッシュされた結果に GridView をバインドしてはどうでしょうか。

手順 4: ObjectDataSource を使用してデータをキャッシュする

いくつかのプロパティを設定するだけで、取得したデータを ASP.NET データ キャッシュに自動的にキャッシュするように ObjectDataSource を構成できます。 次の一覧は、ObjectDataSource のキャッシュ関連のプロパティをまとめたものです。

  • キャッシュを有効にするには、EnableCaching を true に設定する必要があります。 既定値は、false です。
  • CacheDuration データがキャッシュされる期間 (単位: 秒)。 既定値は 0 です。 ObjectDataSource は、EnableCachingtrue され、 CacheDuration が 0 より大きい値に設定されている場合にのみ、データをキャッシュします。
  • CacheExpirationPolicy は、 Absolute または Slidingに設定できます。 Absolute の場合、ObjectDataSource は取得したデータを CacheDuration 秒間キャッシュします。Sliding の場合、データは CacheDuration 秒間アクセスされなかった後にのみ有効期限が切れます。 既定値は、Absolute です。
  • CacheKeyDependency では、このプロパティを使用して、ObjectDataSource のキャッシュ エントリを既存のキャッシュ依存関係に関連付けます。 ObjectDataSource のデータ エントリは、関連する CacheKeyDependency を期限切れにすることで、キャッシュから早期に削除できます。 このプロパティは、SQL キャッシュの依存関係を ObjectDataSource のキャッシュに関連付けるために最も一般的に使用されます。これは、今後の「SQL キャッシュ依存関係の使用」チュートリアルで説明するトピックです。

ProductsDataSource ObjectDataSource を構成し、そのデータを絶対スケールで 30 秒間キャッシュします。 ObjectDataSource の EnableCaching プロパティを 30 に true 設定し、その CacheDuration プロパティを 30 に設定します。 CacheExpirationPolicy プロパティは既定値の Absoluteのままにします。

Configure the ObjectDataSource to Cache its Data for 30 Seconds

図 11: ObjectDataSource を構成してデータを 30 秒間キャッシュします (クリックするとフルサイズの画像が表示されます)

変更内容を保存し、ブラウザーでこのページに再びアクセスします。 "Selecting イベント発生" テキストは、最初にページにアクセスしたときに表示されます (最初はデータがキャッシュに入っていないため)。 ただし、[ポストバック] ボタンのクリック、並べ替え、ページング、または [編集] ボタンまたは [キャンセル] ボタンのクリックによってトリガーされる後続のポストバックでは、"Selecting イベント発生" テキストは再表示されません。 これは、Selecting ObjectDataSource が基になるオブジェクトからデータを取得した場合にのみイベントが発生するためです。データが Selecting データ キャッシュからプルされた場合、イベントは発生しません。

30 秒後、データはキャッシュから削除されます。 ObjectDataSource の InsertUpdate、または Delete メソッドが呼び出された場合も、データがキャッシュから削除されます。 その結果、30 秒が経過するか、[更新] ボタンがクリックされた後、並べ替え、ページング、または [編集] または [キャンセル] ボタンをクリックすると、ObjectDataSource は基になるオブジェクトからデータを取得し、Selecting イベントが発生したときに "Selecting イベント発生" テキストを表示します。 返されたこれらの結果は、データ キャッシュに戻されます。

Note

"Selecting イベント発生" テキストが頻繁に表示される場合は、ObjectDataSource がキャッシュされたデータで動作していると思われる場合でも、メモリの制約が原因である可能性があります。 空きメモリが不足している場合は、ObjectDataSource によってキャッシュに追加されたデータが削除されている可能性があります。 ObjectDataSource がデータを正しくキャッシュしていないように見える場合、または散発的にデータのみをキャッシュしている場合は、一部のアプリケーションを閉じてメモリを解放してから、もう一度やり直してください。

図 12 は、ObjectDataSource のキャッシュ ワークフローを示しています。 "Selecting イベント発生" テキストが画面に表示されるのは、データがキャッシュに存在せず、基になるオブジェクトから取得する必要があったためです。 ただし、このテキストが表示されない場合は、キャッシュからデータを入手できたということです。 キャッシュからデータが返されると、基になるオブジェクトへの呼び出しが起こらないため、データベース クエリは実行されません。

The ObjectDataSource Stores and Retrieves its Data from the Data Cache

図 12: ObjectDataSource は、データ キャッシュからデータを格納および取得します

各 ASP.NET アプリケーションには、すべてのページと訪問者で共有される独自のデータ キャッシュ インスタンスがあります。 つまり、ObjectDataSource によってデータ キャッシュに格納されているデータも、ページにアクセスするすべてのユーザー間で同様に共有されます。 これを確認するには、ブラウザーで ObjectDataSource.aspx ページを開きます。 ページに初めてアクセスすると、"Selecting イベント発生" テキストが表示されます (キャッシュに追加されたデータが以前のテストによって削除されたと仮定します)。 2 番目のブラウザー インスタンスを開き、最初のブラウザー インスタンスから 2 番目のブラウザー インスタンスに URL をコピーして貼り付けます。 2 番目のブラウザー インスタンスでは、最初のキャッシュされたデータと同じデータを使用しているため、"Selecting イベント発生" テキストは表示されません。

取得したデータをキャッシュに挿入するとき、ObjectDataSource は次を含むキャッシュ キー値を使用します: CacheDuration および CacheExpirationPolicy のプロパティ値。TypeName プロパティで指定される、ObjectDataSource が使用する基になるビジネス オブジェクトのタイプ (この例では ProductsBLL)。SelectMethod プロパティの値、および SelectParameters コレクション内のパラメータの名前と値。およびカスタム ページングを実装するときに使用される StartRowIndex および MaximumRows プロパティの値。

これらのプロパティの組み合わせとしてキャッシュ キー値を作成すると、これらの値が変更されても一意のキャッシュ エントリが保証されます。 たとえば、過去のチュートリアルでは、指定したカテゴリのすべての製品を返す ProductsBLL クラスの GetProductsByCategoryID(categoryID) の使い方を見てきました。 あるユーザーがこのページを訪れ、CategoryID の値が1の飲料を見るかもしれません。 ObjectDataSource が SelectParameters の値を無視して結果をキャッシュした場合、飲料製品がキャッシュにある間に他のユーザーが調味料を表示するためにページにアクセスすると、調味料ではなくキャッシュされた飲料製品が表示されます。 SelectParametersの値を含むこれらのプロパティによってキャッシュ キーを変更することで、ObjectDataSource は飲料と調味料に対して個別のキャッシュ エントリを保持します。

古いデータに関する懸念事項

ObjectDataSource は、InsertUpdate、または Delete のいずれかのメソッドが呼び出されたときに、その項目をキャッシュから自動的に削除します。 これにより、ページを介してデータが変更されたときにキャッシュ エントリをクリアすることで、古いデータから保護できます。 ただし、キャッシュを使用している ObjectDataSource では、古いデータが表示される可能性があります。 最も単純なケースでは、データベース内でデータが直接変更されることが原因です。 データベース管理者が、データベース内のレコードの一部を変更するスクリプトを実行しただけかもしれません。

このシナリオは、もっと微妙な形で展開される可能性もあります。 ObjectDataSource は、データ変更メソッドの 1 つが呼び出されたときにその項目をキャッシュから削除しますが、削除対象となるキャッシュされた項目は、ObjectDataSource のプロパティ値の特定の組み合わせ (CacheDurationTypeNameSelectMethod など) です。 異なる SelectMethods または SelectParameters を使用する 2 つの ObjectDataSource があり、同じデータを更新できる場合、ある ObjectDataSource が行を更新して自身のキャッシュ エントリを無効にしても、2 番目の ObjectDataSource に対応する行はキャッシュされたエントリから提供されます。 この機能を表示するページを作成することをお勧めします。 キャッシュを使用し、ProductsBLL クラスの GetProducts() メソッドからデータを取得するように構成された ObjectDataSource からデータをプルする、編集可能な GridView を表示するページを作成します。 別の編集可能な GridView と ObjectDataSource をこのページ (または別のページ) に追加しますが、この 2 番目の ObjectDataSource では GetProductsByCategoryID(categoryID) メソッドを使用します。 2 つの ObjectDataSource の SelectMethod プロパティは異なるため、それぞれ独自のキャッシュ値を持ちます。 あるグリッドで製品を編集した場合、次回データを (ページング、並べ替えなどによって) 他のグリッドにバインドし直す場合、古いキャッシュされたデータが引き続き提供され、もう一方のグリッドから行われた変更は反映されません。

つまり、データが古くなる可能性があっても構わない場合にのみ時間ベースの有効期限を使用し、データの鮮度が重要なシナリオでは有効期限を短くします。 古いデータが許容できない場合は、キャッシュを削除するか、SQL キャッシュの依存関係を使用します (キャッシュするのがデータベース データであると仮定します)。 SQL キャッシュの依存関係については、今後のチュートリアルで説明します。

まとめ

このチュートリアルでは、ObjectDataSource の組み込みのキャッシュ機能について説明しました。 いくつかのプロパティを設定するだけで、指定した SelectMethod から返された結果を ASP.NET データ キャッシュにキャッシュするように ObjectDataSource に指示できます。 CacheDuration プロパティと CacheExpirationPolicy プロパティは、アイテムがキャッシュされる期間と、アイテムが絶対有効期限であるかスライディング有効期限であるかを示します。 CacheKeyDependency プロパティは、ObjectDataSource のすべてのキャッシュ エントリを既存のキャッシュ依存関係に関連付けます。 これは、時間ベースの有効期限に達する前に ObjectDataSource のエントリをキャッシュから削除するために使用でき、通常は SQL キャッシュの依存関係と共に使用されます。

ObjectDataSource は単にその値をデータ キャッシュにキャッシュするため、ObjectDataSource の組み込み機能をプログラムで複製できます。 ObjectDataSource ではこの機能がすぐに使用できるため、プレゼンテーション レイヤーでこれを行っても意味はありませんが、アーキテクチャの別のレイヤーにキャッシュ機能を実装できます。 そのためには、ObjectDataSource で使用されるのと同じロジックを繰り返す必要があります。 次のチュートリアルでは、アーキテクチャ内からデータ キャッシュをプログラムで操作する方法について説明します。

プログラミングに満足!

もっと読む

この記事で説明したトピックの詳細については、次のリソースを参照してください。

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Teresa Murphy でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。