このチュートリアルでは、引き続き SqlDataSource コントロールを確認し、パラメーター化されたクエリを定義する方法について説明します。 パラメーターは、宣言とプログラムの両方で指定でき、クエリ文字列、セッション状態、その他のコントロールなど、さまざまな場所からプルできます。
イントロダクション
前のチュートリアルでは、SqlDataSource コントロールを使用してデータベースから直接データを取得する方法について説明しました。 データ ソースの構成ウィザードを使用して、データベースを選択し、テーブルまたはビューから返す列を選択します。カスタム SQL ステートメントを入力します。ストアド プロシージャを使用します。 テーブルまたはビューから列を選択するか、カスタム SQL ステートメントを入力するかに関係なく、SqlDataSource コントロールの SelectCommand
プロパティには、結果として生成されるアドホック SQL SELECT
ステートメントが割り当てられます。この SELECT
ステートメントは、SqlDataSource の Select()
メソッドが呼び出されたときに実行されます (プログラムによって、またはデータ Web コントロールから自動的に)。
前のチュートリアルのデモで使用した SQL SELECT
ステートメントには、 WHERE
句が不足しています。
SELECT
ステートメントでは、WHERE
句を使用して、返される結果を制限できます。 たとえば、50.00 ドルを超える製品の名前を表示するには、次のクエリを使用できます。
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
通常、 WHERE
句で使用される値は、クエリ文字列値、セッション変数、ページ上の Web コントロールからのユーザー入力など、外部ソースによって決まります。 このような入力は、パラメーターを使用して指定されるのが理想的 です。 Microsoft SQL Server では、パラメーターは次のように @parameterName
を使用して示されます。
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
SqlDataSource は、パラメーター化されたクエリをサポートしています。パラメーター化されたクエリは、 SELECT
ステートメントと、 INSERT
、 UPDATE
、 DELETE
ステートメントの両方に対応しています。 さらに、パラメーター値は、クエリ文字列、セッション状態、ページ上のコントロールなどのさまざまなソースから自動的にプルしたり、プログラムで割り当てたりすることができます。 このチュートリアルでは、パラメーター化されたクエリを定義する方法と、宣言型とプログラム型の両方でパラメーター値を指定する方法について説明します。
注
前のチュートリアルでは、最初の 46 個のチュートリアルで選択した ObjectDataSource を SqlDataSource と比較し、その概念の類似点を確認しました。 これらの類似点は、パラメーターにも及びます。 ビジネス ロジック レイヤー内のメソッドの入力パラメーターにマップされた ObjectDataSource のパラメーター。 SqlDataSource では、パラメーターは SQL クエリ内で直接定義されます。 どちらのコントロールにも、 Select()
、 Insert()
、 Update()
、および Delete()
メソッドのパラメーターのコレクションがあり、どちらも、定義済みのソース (クエリ文字列値、セッション変数など) からこれらのパラメーター値を設定したり、プログラムによって割り当てたりすることができます。
パラメーター化クエリの作成
SqlDataSource コントロールのデータ ソースの構成ウィザードには、データベース レコードを取得するために実行するコマンドを定義するための 3 つの手段があります。
- 既存のテーブルまたはビューから列を選択すると、
- カスタム SQL ステートメントを入力するか、
- ストアド プロシージャを選択する
既存のテーブルまたはビューから列を選択する場合は、[ WHERE
句の追加] ダイアログ ボックスで WHERE
句のパラメーターを指定する必要があります。 ただし、カスタム SQL ステートメントを作成するときは、パラメーターを直接 WHERE
句に入力できます (各パラメーターを示すために @parameterName
を使用します)。 ストアド プロシージャは 1 つ以上の SQL ステートメントで構成され、これらのステートメントはパラメーター化できます。 ただし、SQL ステートメントで使用されるパラメーターは、ストアド プロシージャに入力パラメーターとして渡す必要があります。
パラメーター化されたクエリの作成は、SqlDataSource の SelectCommand
の指定方法によって異なるため、3 つの方法をすべて見てみましょう。 開始するには、ParameterizedQueries.aspx
フォルダーのSqlDataSource
ページを開き、ツールボックスからデザイナーに SqlDataSource コントロールをドラッグし、そのID
をProducts25BucksAndUnderDataSource
に設定します。 次に、コントロールのスマート タグから [データ ソースの構成] リンクをクリックします。 使用するデータベース (NORTHWINDConnectionString
) を選択し、[次へ] をクリックします。
手順 1: テーブルまたはビューから列を選択するときの WHERE 句の追加
SqlDataSource コントロールを使用してデータベースから返すデータを選択する場合、データ ソースの構成ウィザードでは、既存のテーブルまたはビューから返す列を選択できます (図 1 を参照)。 これにより、SQL SELECT
ステートメントが自動的に構築されます。これは、SqlDataSource の Select()
メソッドが呼び出されたときにデータベースに送信されます。 前のチュートリアルで行ったように、ドロップダウン リストから Products テーブルを選択し、 ProductID
、 ProductName
、および UnitPrice
列を確認します。
図 1: テーブルまたはビューから返す列を選択します (フルサイズの画像を表示する 場合はクリックします)
WHERE
ステートメントにSELECT
句を含めるには、[WHERE
] ボタンをクリックすると、[WHERE
句の追加] ダイアログ ボックスが表示されます (図 2 を参照)。
SELECT
クエリによって返される結果を制限するパラメーターを追加するには、最初にデータをフィルター処理する列を選択します。 次に、フィルター処理に使用する演算子 (=、 <、 <=、 >など) を選択します。 最後に、クエリ文字列やセッション状態など、パラメーターの値のソースを選択します。 パラメーターを構成したら、[追加] ボタンをクリックして、 SELECT
クエリに含めます。
この例では、 UnitPrice
値が $25.00 以下の結果のみを返します。 したがって、[列] ドロップダウン リストから UnitPrice
を選択し、[演算子] ドロップダウン リストから <= を選択します。 ハードコーディングされたパラメーター値 ($25.00 など) を使用する場合、またはパラメーター値をプログラムで指定する場合は、[ソース] ドロップダウン リストから [なし] を選択します。 次に、[値] テキストボックス 25.00 にハードコーディングされたパラメーター値を入力し、[追加] ボタンをクリックしてプロセスを完了します。
図 2: [ WHERE
句の追加] ダイアログ ボックスから返される結果を制限する (フルサイズの画像を表示する をクリックします)。
パラメーターを追加した後、[OK] をクリックしてデータ ソースの構成ウィザードに戻ります。 ウィザードの下部にある SELECT
ステートメントに、WHERE
という名前のパラメーターを含む @UnitPrice
句が含まれるようになりました。
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
注
[WHERE
句の追加] ダイアログ ボックスで WHERE
句に複数の条件を指定した場合、ウィザードはそれらを AND
演算子と結合します。
OR
句 (WHERE
など) にWHERE UnitPrice <= @UnitPrice OR Discontinued = 1
を含める必要がある場合は、カスタム SQL ステートメント画面でSELECT
ステートメントをビルドする必要があります。
SqlDataSource の構成を完了し ([次へ]、[完了] の順にクリック)、SqlDataSource の宣言型マークアップを調べます。 マークアップに <SelectParameters>
コレクションが含まれるようになりました。これにより、 SelectCommand
内のパラメーターのソースがスペル アウトされます。
<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
<SelectParameters>
<asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
</SelectParameters>
</asp:SqlDataSource>
SqlDataSource の Select()
メソッドが呼び出されると、データベースに送信される前に、UnitPrice
パラメーター値 (25.00) が@UnitPrice
のSelectCommand
パラメーターに適用されます。 結果として、 Products
テーブルから返されるのは 25.00 ドル以下の製品だけです。 これを確認するには、ページに GridView を追加し、このデータ ソースにバインドしてから、ブラウザーを使用してページを表示します。 図 3 に示すように、25.00 ドル以下の製品のみが表示されます。
図 3: $25.00 以下の製品のみが表示されます (フルサイズの画像を表示する 場合はクリックします)
手順 2: カスタム SQL ステートメントにパラメーターを追加する
カスタム SQL ステートメントを追加するときは、 WHERE
句を明示的に入力するか、クエリ ビルダーの [フィルター] セルに値を指定できます。 これを示すために、価格が特定のしきい値より小さい製品だけを GridView に表示してみましょう。 まず、 ParameterizedQueries.aspx
ページに TextBox を追加して、ユーザーからこのしきい値を収集します。 TextBox の ID
プロパティを MaxPrice
に設定します。 Button Web コントロールを追加し、その Text
プロパティを [一致する製品の表示] に設定します。
次に、GridView をページにドラッグし、スマート タグから ProductsFilteredByPriceDataSource
という名前の新しい SqlDataSource を作成することを選択します。 データ ソースの構成ウィザードから、[カスタム SQL ステートメントまたはストアド プロシージャの指定] 画面 (図 4 を参照) に進み、次のクエリを入力します。
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice
(手動またはクエリ ビルダーを使用して) クエリを入力した後、[次へ] をクリックします。
図 4: パラメーター値以下の製品のみを返します (フルサイズの画像を表示する をクリックします)。
クエリにはパラメーターが含まれるため、ウィザードの次の画面でパラメーター値のソースの入力を求められます。 [パラメーター ソース] ドロップダウン リストから [コントロール] を選択し、[ControlID] ドロップダウン リストから MaxPrice
(TextBox コントロールの ID
値) を選択します。 また、ユーザーがテキストを MaxPrice
TextBox に入力していない場合に使用する省略可能な既定値を入力することもできます。 当面は、既定値を入力しないでください。
図 5: MaxPrice
テキスト ボックスの Text
プロパティは、パラメーター ソースとして使用されます (フルサイズの画像を表示する をクリックします)。
[次へ]、[完了] の順にクリックして、データ ソースの構成ウィザードを完了します。 GridView、TextBox、Button、および SqlDataSource の宣言型マークアップは次のとおりです。
Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
HtmlEncode="False" DataFormatString="{0:c}"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT ProductName, UnitPrice
FROM Products WHERE UnitPrice <= @MaximumPrice">
<SelectParameters>
<asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
SqlDataSource の <SelectParameters>
セクション内のパラメーターは ControlParameter
であり、 ControlID
や PropertyName
などの追加のプロパティが含まれていることに注意してください。 SqlDataSource の Select()
メソッドが呼び出されると、 ControlParameter
は指定された Web コントロール プロパティから値を取得し、 SelectCommand
内の対応するパラメーターに割り当てます。 この例では、 MaxPrice
の Text プロパティが @MaxPrice
パラメーター値として使用されます。
ブラウザーでこのページを表示するには、少し時間がかかります。 最初にページにアクセスしたとき、または MaxPrice
TextBox に値がない場合は常に、GridView にレコードが表示されません。
図 6: MaxPrice
テキスト ボックスが空の場合、レコードは表示されません (フルサイズの画像を表示する をクリックします)。
製品が表示されない理由は、パラメーター値の空の文字列が既定でデータベース NULL
値に変換されるためです。
[UnitPrice] <= NULL
の比較は常に False と評価されるため、結果は返されません。
テキストボックスに値 (5.00 など) を入力し、[Display Matching Products]\(一致する製品の表示\) ボタンをクリックします。 ポストバック時に、SqlDataSource は、パラメーター ソースの 1 つが変更されたことを GridView に通知します。 その結果、GridView は SqlDataSource に再バインドされ、$5.00 以下の製品が表示されます。
図 7: $5.00 以下の製品が表示されます (フルサイズの画像を表示する をクリックします)。
最初にすべての製品を表示する
ページが最初に読み込まれたときに製品を表示しないのではなく、すべての製品を表示したいと考えています。
MaxPrice
TextBox が空の場合は常にすべての製品を一覧表示する方法の 1 つは、Northwind Traders が単価が 1,000,000 ドルを超える在庫を持つ可能性が低いため、パラメーターの既定値を 1000000 のような非常に高い値に設定することです。 ただし、このアプローチは近視眼であり、他の状況では機能しない可能性があります。
前のチュートリアル - 宣言型パラメーター と 、DropDownList を使用したマスター/詳細フィルター処理 でも、同様の問題が発生しました。 ソリューションでは、このロジックをビジネス ロジック レイヤーに配置しました。 具体的には、BLL は受信値を調べ、 NULL
または予約された値がある場合、呼び出しはすべてのレコードを返す DAL メソッドにルーティングされました。 受信値が通常のフィルター値の場合、指定された値でパラメーター化された WHERE
句を使用する SQL ステートメントを実行する DAL メソッドに対して呼び出しが行われました。
残念ながら、SqlDataSource を使用する場合はアーキテクチャをバイパスします。 代わりに、 @MaximumPrice
パラメーターが NULL
または予約値である場合に、すべてのレコードをインテリジェントに取得するように SQL ステートメントをカスタマイズする必要があります。 この演習では、 @MaximumPrice
パラメーターが -1.0
と等しい場合 は、すべての レコードが返されるようにします (-1.0
は、負の UnitPrice
値を持つことができないため、予約値として機能します)。 これを実現するには、次の SQL ステートメントを使用します。
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
このWHERE
句は、 パラメーターが @MaximumPrice
と等しい場合-1.0
レコードを返します。 パラメーター値が -1.0
されていない場合は、 UnitPrice
が @MaximumPrice
パラメーター値以下の製品のみが返されます。
@MaximumPrice
パラメーターの既定値を-1.0
に設定すると、最初のページ読み込み時 (または MaxPrice
TextBox が空の場合)、@MaximumPrice
の値は -1.0
になり、すべての製品が表示されます。
図 8: MaxPrice
TextBox が空の場合、すべての製品が表示されるようになりました (フルサイズの画像を表示する をクリックします)。
このアプローチでは、いくつかの注意事項があります。 まず、SQL クエリでのパラメーターのデータ型が、そのパラメーターの使用法によって推論されることを認識します。
WHERE
句を @MaximumPrice = -1.0
から @MaximumPrice = -1
に変更すると、ランタイムはパラメーターを整数として扱います。 その後、 MaxPrice
TextBox を 10 進値 (5.00 など) に割り当てようとすると、5.00 を整数に変換できないため、エラーが発生します。 これを解決するには、@MaximumPrice = -1.0
句でWHERE
を使用するか、ControlParameter
オブジェクトの Type
プロパティを Decimal に設定します。
第 2 に、 OR @MaximumPrice = -1.0
を WHERE
句に追加すると、クエリ エンジンは UnitPrice
にインデックスを使用できないため (存在すると仮定して)、テーブル スキャンが行われます。
Products
テーブルに十分な数のレコードがある場合、パフォーマンスに影響を与える可能性があります。 このロジックをストアド プロシージャに移動すると、すべてのレコードを返す必要がある場合は、IF
ステートメントで SELECT
テーブルから Products
句を使用せずにWHERE
クエリを実行するか、WHERE
句にUnitPrice
条件だけが含まれるため、インデックスを使用できるようになります。
手順 3: パラメーター化ストアド プロシージャの作成と使用
ストアド プロシージャには、ストアド プロシージャ内で定義された SQL ステートメントで使用できる一連の入力パラメーターを含めることができます。 入力パラメーターを受け取るストアド プロシージャを使用するように SqlDataSource を構成する場合、これらのパラメーター値は、アドホック SQL ステートメントと同じ手法を使用して指定できます。
SqlDataSource でストアド プロシージャを使用する方法を説明するために、 GetProductsByCategory
という名前の Northwind データベースに新しいストアド プロシージャを作成します。このデータベースは、 @CategoryID
という名前のパラメーターを受け取り、 CategoryID
列が @CategoryID
と一致する製品のすべての列を返します。 ストアド プロシージャを作成するには、サーバー エクスプローラーに移動し、 NORTHWND.MDF
データベースにドリルダウンします。 (サーバー エクスプローラーが表示されない場合は、[表示] メニューに移動し、[サーバー エクスプローラー] オプションを選択して表示します)。
NORTHWND.MDF
データベースで、[ストアド プロシージャ] フォルダーを右クリックし、[新しいストアド プロシージャの追加] を選択し、次の構文を入力します。
CREATE PROCEDURE dbo.GetProductsByCategory
(
@CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID
[保存] アイコン (または Ctrl + S) をクリックしてストアド プロシージャを保存します。 ストアド プロシージャをテストするには、ストアド プロシージャ フォルダーから右クリックし、[実行] を選択します。 これにより、ストアド プロシージャのパラメーター (このインスタンスでは @CategoryID
) の入力が求められます。その後、結果が [出力] ウィンドウに表示されます。
図 9: GetProductsByCategory
1 で実行した場合の@CategoryID
ストアド プロシージャ (フルサイズの画像を表示する] をクリックします)
このストアド プロシージャを使用して、GridView の [飲料] カテゴリのすべての製品を表示してみましょう。 ページに新しい GridView を追加し、 BeverageProductsDataSource
という名前の新しい SqlDataSource にバインドします。 [カスタム SQL ステートメントまたはストアド プロシージャの指定] 画面に進み、[ストアド プロシージャ] ラジオ ボタンを選択し、ドロップダウン リストから GetProductsByCategory
ストアド プロシージャを選択します。
図 10: Drop-Down の一覧から GetProductsByCategory
ストアド プロシージャを選択します (フルサイズの画像を表示する をクリックします)。
ストアド プロシージャは入力パラメーター (@CategoryID
) を受け取るので、[次へ] をクリックすると、このパラメーターの値のソースを指定するように求められます。 飲料 CategoryID
は 1 なので、[パラメーター ソース] ドロップダウン リストを [なし] のままにし、[DefaultValue] ボックスに「1」と入力します。
図 11: Hard-Coded 値 1 を使用して飲料カテゴリの製品を返す (フルサイズの画像を表示する をクリックします)。
次の宣言型マークアップが示すように、ストアド プロシージャを使用する場合、SqlDataSource の SelectCommand
プロパティはストアド プロシージャの名前に設定され、 SelectCommandType
プロパティ は StoredProcedure
に設定され、 SelectCommand
がアドホック SQL ステートメントではなくストアド プロシージャの名前であることを示します。
<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
ブラウザーでページをテストします。 [飲み物] カテゴリに属する製品のみが表示されますが、 ストアド プロシージャはGetProductsByCategory
テーブルからすべての列を返すので、Products
製品フィールドが表示されます。 もちろん、GridView の [列の編集] ダイアログ ボックスから GridView に表示されるフィールドを制限またはカスタマイズすることもできます。
図 12: すべての飲料が表示されます (フルサイズの画像を表示する をクリックします)。
手順 4: SqlDataSource の Select() ステートメントをプログラムで呼び出す
前のチュートリアルとこのチュートリアルで見た例では、SqlDataSource コントロールを GridView に直接バインドしました。 ただし、SqlDataSource コントロールのデータは、コード内でプログラムからアクセスして列挙できます。 これは、データを検査するためにクエリを実行する必要があるが、表示する必要がない場合に特に便利です。 データベースに接続し、コマンドを指定して結果を取得するために、すべての定型 ADO.NET コードを記述する必要はなく、SqlDataSource でこの単調なコードを処理できます。
SqlDataSource のデータをプログラムで操作する方法を説明するために、上司から、ランダムに選択されたカテゴリとその関連製品の名前を表示する Web ページを作成する要求を受け取ったとします。 つまり、ユーザーがこのページにアクセスすると、 Categories
テーブルからカテゴリをランダムに選択し、カテゴリ名を表示して、そのカテゴリに属する製品を一覧表示します。
これを実現するには、2 つの SqlDataSource コントロールが必要です。1 つは、 Categories
テーブルからランダムなカテゴリを取得し、もう 1 つはカテゴリの製品を取得します。 この手順では、ランダムなカテゴリ レコードを取得する SqlDataSource を構築します。手順 5 では、カテゴリの製品を取得する SqlDataSource の作成について説明します。
まず、sqlDataSource を ParameterizedQueries.aspx
に追加し、その ID
を RandomCategoryDataSource
に設定します。 次の SQL クエリを使用するように構成します。
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID()
は、ランダムな順序で並べ替えられたレコードを返します ( 「 NEWID()
を使用してレコードをランダムに並べ替える」を参照)。
SELECT TOP 1
は、結果セットから最初のレコードを返します。 一緒に言えば、このクエリは、ランダムに選択された単一のカテゴリから CategoryID
と CategoryName
列の値を返します。
カテゴリの CategoryName
値を表示するには、Label Web コントロールをページに追加し、その ID
プロパティを CategoryNameLabel
に設定し、その Text
プロパティをクリアします。 SqlDataSource コントロールからデータをプログラムで取得するには、その Select()
メソッドを呼び出す必要があります。
Select()
メソッドは、DataSourceSelectArguments
型の単一の入力パラメーターを受け取ります。これは、返される前にデータをメッセージ化する方法を指定します。 これには、データの並べ替えとフィルター処理に関する手順が含まれる場合があり、SqlDataSource コントロールのデータを並べ替えたりページングしたりするときに、データ Web コントロールによって使用されます。 ただし、この例では、返される前にデータを変更する必要がないため、 DataSourceSelectArguments.Empty
オブジェクトを渡します。
Select()
メソッドは、IEnumerable
を実装するオブジェクトを返します。 返される正確な型は、SqlDataSource コントロールの DataSourceMode
プロパティの値によって異なります。 前のチュートリアルで説明したように、このプロパティは DataSet
または DataReader
のいずれかの値に設定できます。
DataSet
に設定すると、Select()
メソッドは DataView オブジェクトを返します。DataReader
に設定すると、IDataReader
を実装するオブジェクトが返されます。
RandomCategoryDataSource
SqlDataSource には DataSourceMode
プロパティが DataSet
(既定値) に設定されているため、DataView オブジェクトを操作します。
次のコードは、 RandomCategoryDataSource
SqlDataSource から DataView としてレコードを取得する方法と、最初の DataView 行から CategoryName
列の値を読み取る方法を示しています。
protected void Page_Load(object sender, EventArgs e)
{
// Get the data from the SqlDataSource as a DataView
DataView randomCategoryView =
(DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
if (randomCategoryView.Count > 0)
{
// Assign the CategoryName value to the Label
CategoryNameLabel.Text =
string.Format("Here are Products in the {0} Category...",
randomCategoryView[0]["CategoryName"].ToString());
}
}
randomCategoryView[0]
は、DataView 内の最初の DataRowView
を返します。
randomCategoryView[0]["CategoryName"]
は、この最初の行の CategoryName
列の値を返します。 DataView はゆるく型付けされていることに注意してください。 特定の列値を参照するには、列の名前を文字列 (この場合は CategoryName) として渡す必要があります。 図 13 は、ページを表示するときに CategoryNameLabel
に表示されるメッセージを示しています。 もちろん、実際に表示されるカテゴリ名は、ページにアクセスするたびに RandomCategoryDataSource
SqlDataSource によってランダムに選択されます (ポストバックを含む)。
図 13: ランダムに選択されたカテゴリの名前が表示されます (フルサイズの画像を表示する をクリックします)。
注
SqlDataSource コントロールの DataSourceMode
プロパティが DataReader
に設定されている場合、 Select()
メソッドからの戻り値を IDataReader
にキャストする必要がありました。 最初の行から CategoryName
列の値を読み取るために、次のようなコードを使用します。
if (randomCategoryReader.Read())
{
string categoryName = randomCategoryReader["CategoryName"].ToString();
...
}
SqlDataSource でカテゴリがランダムに選択されたので、カテゴリの製品を一覧表示する GridView を追加する準備ができました。
注
ラベル Web コントロールを使用してカテゴリの名前を表示するのではなく、ページに FormView または DetailsView を追加し、SqlDataSource にバインドすることもできます。 ただし、Label を使用すると、SqlDataSource の Select()
ステートメントをプログラムで呼び出し、その結果のデータをコードで操作する方法を調べることができます。
手順 5: プログラムによるパラメーター値の割り当て
このチュートリアルでこれまでに見てきたすべての例では、ハードコーディングされたパラメーター値または定義済みのパラメーター ソース (クエリ文字列値、ページ上の Web コントロールなど) から取得したパラメーター値を使用しています。 ただし、SqlDataSource コントロールのパラメーターをプログラムで設定することもできます。 現在の例を完了するには、指定したカテゴリに属するすべての製品を返す SqlDataSource が必要です。 この SqlDataSource には、CategoryID
イベント ハンドラーの CategoryID
SqlDataSource によって返されるRandomCategoryDataSource
列の値に基づいて値を設定する必要があるPage_Load
パラメーターがあります。
まず、ページに GridView を追加し、 ProductsByCategoryDataSource
という名前の新しい SqlDataSource にバインドします。 手順 3. と同様に、 GetProductsByCategory
ストアド プロシージャを呼び出すように SqlDataSource を構成します。 この既定値はプログラムで設定するため、[パラメーター ソース] ドロップダウン リストは [なし] のままにしますが、既定値は入力しないでください。
図 14: パラメーターソースまたは既定値を指定しない (フルサイズの画像を表示する をクリックします)
SqlDataSource ウィザードを完了すると、結果の宣言型マークアップは次のようになります。
<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
DefaultValue
イベント ハンドラーで、CategoryID
パラメーターのPage_Load
をプログラムで割り当てることができます。
// Assign the ProductsByCategoryDataSource's
// CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
randomCategoryView[0]["CategoryID"].ToString();
この追加により、ページには、ランダムに選択されたカテゴリに関連付けられている製品を表示する GridView が含まれます。
図 15: パラメーターのソースまたは既定値を指定しない (フルサイズの画像を表示する をクリックします)
概要
SqlDataSource を使用すると、ページ開発者は、パラメーター値をハードコーディングしたり、定義済みのパラメーター ソースからプルしたり、プログラムで割り当てたりできるパラメーター化クエリを定義できます。 このチュートリアルでは、アドホック SQL クエリとストアド プロシージャの両方について、データ ソースの構成ウィザードからパラメーター化されたクエリを作成する方法について説明しました。 また、ハードコーディングされたパラメーター ソース、Web コントロールをパラメーター ソースとして使用し、プログラムでパラメーター値を指定する方法についても説明しました。
ObjectDataSource と同様に、SqlDataSource には基になるデータを変更する機能も用意されています。 次のチュートリアルでは、SqlDataSource で INSERT
、 UPDATE
、および DELETE
ステートメントを定義する方法について説明します。 これらのステートメントが追加されたら、GridView、DetailsView、および FormView コントロールに固有の組み込みの挿入、編集、および削除機能を利用できます。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・セルフ ASP.NET 24時間で2.0です。 彼には mitchell@4GuysFromRolla.comで連絡できます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Scott Clyde、Randell Schmidt、Ken Pespisa でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、mitchell@4GuysFromRolla.comにメッセージを送ってください。