パラメーター化されたクエリと SqlDataSource を使用する (C#)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、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 では、パラメーター化されたクエリ (ステートメントと 、、および UPDATEINSERTステートメントのSELECT両方) が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.aspxSqlDataSource開き、SqlDataSource コントロールをツールボックスから Designer にドラッグし、その コントロールIDを にProducts25BucksAndUnderDataSource設定します。 次に、コントロールのスマート タグから [データ ソースの構成] リンクをクリックします。 使用するデータベース (NORTHWINDConnectionString) を選択し、[次へ] をクリックします。

手順 1: テーブルまたはビューから列を選択するときに WHERE 句を追加する

SqlDataSource コントロールを使用してデータベースから返すデータを選択する場合、データ ソースの構成ウィザードを使用すると、既存のテーブルまたはビューから返す列を選択できます (図 1 を参照)。 これにより、SQL SELECT ステートメントが自動的に作成されます。これは、SqlDataSource の Select() メソッドが呼び出されたときにデータベースに送信されます。 前のチュートリアルで行ったように、ドロップダウン リストから Products テーブルを選択し、および UnitPrice 列をProductIDProductNameチェックします。

テーブルまたはビューから返す列を選択する

図 1: テーブルまたはビューから返す列を選択する (フルサイズの画像を表示する をクリックします)

ステートメントに句をWHERE含めるには、 ボタンをWHEREクリックすると、[句の追加WHERE] ダイアログ ボックスが表示されます (図 2 をSELECT参照)。 クエリによって返される結果を制限するパラメーターを SELECT 追加するには、最初にデータをフィルター処理する列を選択します。 次に、フィルター処理に使用する演算子 (=、、、<<=、>、など) を選択します。 最後に、クエリ文字列やセッション状態などのパラメーターの値のソースを選択します。 パラメーターを構成したら、[追加] ボタンをクリックしてクエリに SELECT 含めます。

この例では、値が UnitPrice $25.00 以下の結果のみを返します。 したがって、[列] ドロップダウン リストからを選択 UnitPrice し <、[演算子] ドロップダウン リストから = を選択します。 ハードコーディングされたパラメーター値 ($25.00 など) を使用する場合、またはパラメーター値をプログラムで指定する場合は、[ソース] ドロップダウン リストから [なし] を選択します。 次に、[値] ボックス 25.00 にハードコーディングされたパラメーター値を入力し、[追加] ボタンをクリックしてプロセスを完了します。

[WHERE 句の追加] ダイアログ ボックスから返される結果を制限する

図 2: [句の追加 WHERE ] ダイアログ ボックスから返される結果を制限する (クリックするとフルサイズの画像が表示されます)

パラメーターを追加した後、[OK] をクリックしてデータ ソースの構成ウィザードに戻ります。 SELECTウィザードの下部にある ステートメントに、 という名前@UnitPriceのパラメーターをWHERE持つ 句が含まれるようになりました。

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

注意

[句の WHERE 追加 WHERE ] ダイアログ ボックスで句に複数の条件を指定すると、ウィザードによって演算子と AND 結合されます。 句 (などWHERE UnitPrice <= @UnitPrice OR Discontinued = 1) に をORWHERE含める必要がある場合は、カスタム 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 データベースに送信される前に @UnitPrice 、 の パラメーター値 (25.00) が パラメーターに SelectCommand 適用されます。 結果として、$25.00 以下の製品のみがテーブルから Products 返されます。 これを確認するには、ページに GridView を追加し、このデータ ソースにバインドしてから、ブラウザーを使用してページを表示します。 図 3 で確認されているように、$25.00 以下の製品のみが表示されます。

$25.00 以下の製品のみが表示されます

図 3: $25.00 以下の製品のみが表示されます (クリックするとフルサイズの画像が表示されます)

手順 2: カスタム SQL ステートメントへのパラメーターの追加

カスタム SQL ステートメントを追加する場合は、 句を WHERE 明示的に入力するか、クエリ ビルダーの [フィルター] セルに値を指定できます。 これを示すために、価格が特定のしきい値より小さい製品のみを GridView に表示してみましょう。 まず、TextBox をページに追加して、 ParameterizedQueries.aspx このしきい値をユーザーから収集します。 TextBox の プロパティを IDMaxPrice設定します。 Button Web コントロールを追加し、そのプロパティを Text [Display Matching Products]\(一致する製品の表示\) に設定します。

次に、GridView をページにドラッグし、スマート タグから という名前 ProductsFilteredByPriceDataSourceの新しい SqlDataSource を作成することを選択します。 データ ソースの構成ウィザードから、[カスタム SQL ステートメントまたはストアド プロシージャの指定] 画面 (図 4 を参照) に進み、次のクエリを入力します。

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice

クエリを入力した後 (手動またはクエリ ビルダーを使用して)、[次へ] をクリックします。

パラメーター値以下の製品のみを返します

図 4: パラメーター値以下の製品のみを返す (フルサイズの画像を表示する をクリックします)

クエリにはパラメーターが含まれるため、ウィザードの次の画面でパラメーター値のソースの入力を求められます。 [パラメーター ソース] ドロップダウン リストから [コントロール] を選択し MaxPrice 、[ControlID] ドロップダウン リストから (TextBox コントロールの ID 値) を選択します。 また、ユーザーが TextBox にテキストを入力していない場合に使用する省略可能な既定値を MaxPrice 入力することもできます。 当面は、既定値を入力しないでください。

MaxPrice TextBox の Text プロパティは、パラメーター ソースとして使用されます

図 5: MaxPrice TextBox の 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> パラメーターは であり、 ControlParameterPropertyNameなどのControlID追加のプロパティが含まれています。 SqlDataSource の Select() メソッドが呼び出されると、 ControlParameter は指定された Web コントロール プロパティから値を取得し、 内 SelectCommandの対応するパラメーターに割り当てます。 この例では、 MaxPrice パラメーター値として s Text プロパティを @MaxPrice 使用します。

ブラウザーを使用してこのページを表示するには、少し時間がかかります。 最初にページにアクセスするとき、または TextBox に MaxPrice 値がない場合は常に、GridView にレコードは表示されません。

MaxPrice TextBox が空の場合、レコードは表示されません

図 6: TextBox が空の場合 MaxPrice 、レコードは表示されません (フルサイズの画像を表示する をクリックします)

製品が表示されない理由は、パラメーター値の空の文字列が既定でデータベース NULL 値に変換されるためです。 の [UnitPrice] <= NULL 比較は常に False と評価されるため、結果は返されません。

テキスト ボックスに値 (5.00 など) を入力し、[一致する製品の表示] ボタンをクリックします。 ポストバック時に、SqlDataSource は、パラメーター ソースの 1 つが変更されたことを GridView に通知します。 その結果、GridView は SqlDataSource に再バインドされ、$5.00 以下の製品が表示されます。

$5.00 以下の製品が表示されます

図 7: $5.00 以下の製品が表示されます (フルサイズの画像を表示する場合はクリックします)

最初にすべての製品を表示する

ページが最初に読み込まれたときに製品を表示するのではなく、 すべての 製品を表示することもできます。 TextBox が空のときにすべての MaxPrice 製品を一覧表示する方法の 1 つは、Northwind Traders が単価が $1,000,000 を超える在庫を持つ可能性は低いため、パラメーターの既定値を 1000000 のような非常に高い値に設定することです。 ただし、このアプローチは近視であり、他の状況では機能しない可能性があります。

前のチュートリアル - 宣言型パラメーター、DropDownList を使用したマスター/詳細フィルター処理 でも、同様の問題が発生しました。 このソリューションでは、このロジックをビジネス ロジック レイヤーに配置する必要があります。 具体的には、BLL は受信値を調べ、それがまたは予約値である NULL 場合は、すべてのレコードを返す DAL メソッドに呼び出しがルーティングされました。 受信値が通常のフィルター値の場合は、指定された値を持つパラメーター化された WHERE 句を使用する SQL ステートメントを実行する DAL メソッドの呼び出しが行われました。

残念ながら、SqlDataSource を使用する場合はアーキテクチャをバイパスします。 代わりに、パラメーターNULLが または予約値である場合は、すべてのレコードをインテリジェントに取得するように SQL ステートメントを@MaximumPriceカスタマイズする必要があります。 この演習では、 パラメーターが と等しい-1.0場合@MaximumPriceは、すべてのレコードが返されるようにします (-1.0製品に負UnitPriceの値を指定できないため、予約値として機能します)。 これを実現するには、次の SQL ステートメントを使用します。

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

パラメーターが と等しい場合、この WHEREはすべての レコードを @MaximumPrice 返します -1.0。 パラメーター値が でない-1.0場合は、パラメーター値以下@MaximumPriceの製品UnitPriceのみが返されます。 パラメーターの既定値を @MaximumPrice-1.0設定すると、最初のページ読み込み時 (または TextBox が空@MaximumPriceの場合)MaxPrice、 の-1.0値がになり、すべての製品が表示されます。

MaxPrice TextBox が空のときにすべての製品が表示されるようになりました

図 8: テキスト ボックスが空の場合 MaxPrice にすべての製品が表示されるようになりました (フルサイズの画像を表示する をクリックします)

この方法には、注意すべき注意事項がいくつかあります。 まず、パラメーターのデータ型が SQL クエリでの使用によって推論されることを認識します。 句を WHERE から @MaximumPrice = -1.0@MaximumPrice = -1変更すると、ランタイムは パラメーターを整数として扱います。 その後、TextBox を 10 進値 (5.00 など) に割り当て MaxPrice ようとすると、5.00 を整数に変換できないため、エラーが発生します。 これを解決するには、 句で を使用@MaximumPrice = -1.0するか、オブジェクトの Type プロパティを ControlParameter Decimal に設定WHEREします。

第 2 に、 句に をWHERE追加OR @MaximumPrice = -1.0すると、クエリ エンジンは にUnitPriceインデックスを使用できないため (存在する場合)、テーブル スキャンが発生します。 これは、テーブルに十分な数のレコードがある場合、パフォーマンスに影響を Products 与える可能性があります。 より良い方法は、このロジックをストアド プロシージャIFに移動することです。この場合、ステートメントは、すべてのレコードを返す必要があるときに句を使用せずにWHEREテーブルからProductsクエリを実行するか、インデックスWHEREを使用できるように句に条件だけがUnitPrice含まれるクエリを実行SELECTします。

手順 3: パラメーター化ストアド プロシージャの作成と使用

ストアド プロシージャには、ストアド プロシージャ内で定義されている SQL ステートメントで使用できる入力パラメーターのセットを含めることができます。 入力パラメーターを受け取るストアド プロシージャを使用するように SqlDataSource を構成する場合、これらのパラメーター値は、アドホック SQL ステートメントと同じ手法を使用して指定できます。

SqlDataSource でストアド プロシージャを使用する方法を説明するために、 という名前の Northwind データベースに新しいストアド プロシージャを作成します。このデータベースは、 という GetProductsByCategory名前 @CategoryID のパラメーターを受け取り、列が CategoryID と一致するすべての列を返します @CategoryID。 ストアド プロシージャを作成するには、サーバー エクスプローラーに移動し、データベースをドリルダウンしますNORTHWND.MDF。 ([サーバー] エクスプローラーが表示されない場合は、[表示] メニューに移動し、[サーバー エクスプローラー] オプションを選択して表示します)。

データベースから NORTHWND.MDF [ストアド プロシージャ] フォルダーを右クリックし、[新しいストアド プロシージャの追加] を選択し、次の構文を入力します。

CREATE PROCEDURE dbo.GetProductsByCategory
(
      @CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID

[保存] アイコン (または Ctrl + S) をクリックして、ストアド プロシージャを保存します。 ストアド プロシージャを右クリックして [ストアド プロシージャ] フォルダーから [実行] を選択すると、ストアド プロシージャをテストできます。 これにより、ストアド プロシージャのパラメーター (@CategoryIDこのインスタンスでは) の入力が求められます。その後、結果が [出力] ウィンドウに表示されます。

実行された場合の GetProductsByCategory ストアド プロシージャ

図 9: の GetProductsByCategory を 1 で実行した @CategoryID 場合のストアド プロシージャ (フルサイズの画像を表示する場合をクリックします)

このストアド プロシージャを使用して、GridView の [飲料] カテゴリのすべての製品を表示してみましょう。 新しい GridView をページに追加し、 という名前 BeverageProductsDataSourceの新しい SqlDataSource にバインドします。 [カスタム SQL ステートメントまたはストアド プロシージャの指定] 画面に進み、[ストアド プロシージャ] ラジオ ボタンを選択し、ドロップダウン リストからストアド プロシージャを選択 GetProductsByCategory します。

Drop-Down リストから GetProductsByCategory ストアド プロシージャを選択します

図 10: Drop-Down リストからストアド プロシージャを選択 GetProductsByCategory します (フルサイズの画像を表示する 場合はクリックします)

ストアド プロシージャは入力パラメーター (@CategoryID) を受け取るので、[次へ] をクリックすると、このパラメーターの値のソースを指定するように求められます。 飲料 CategoryID は 1 なので、[パラメーター ソース] ドロップダウン リストを [なし] のままにし、[DefaultValue] ボックスに「1」と入力します。

Hard-Coded 値 1 を使用して、飲料カテゴリの製品を返す

図 11: Hard-Coded 値 1 を使用して飲料カテゴリの製品を返す (フルサイズの画像を表示する をクリックします)

次の宣言マークアップが示すように、ストアド プロシージャを使用する場合、SqlDataSource の SelectCommand プロパティはストアド プロシージャの名前に設定され、 プロパティは にStoredProcedure設定されますSelectCommandType。これは、 がアドホック SQL ステートメントではなくストアド プロシージャの名前であることをSelectCommand示します。

<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 コントロールと、カテゴリの製品を Categories 取得するための 2 つの SqlDataSource コントロールが必要です。 この手順では、ランダムなカテゴリ レコードを取得する 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 選択された 1 つのカテゴリから と CategoryName 列の値を返します。

カテゴリの CategoryName 値を表示するには、Label Web コントロールをページに追加し、そのプロパティを IDCategoryNameLabel設定し、そのプロパティを Text クリアします。 SqlDataSource コントロールからプログラムでデータを取得するには、その Select() メソッドを呼び出す必要があります。 メソッドではSelect()、 型DataSourceSelectArgumentsの単一の入力パラメーターが必要です。これは、返される前にデータをメッセージ化する方法を指定します。 これには、データの並べ替えとフィルター処理の手順が含まれます。また、SqlDataSource コントロールのデータを並べ替えたりページングしたりする際に、データ Web コントロールによって使用されます。 ただし、この例では、返される前にデータを変更する必要がないため、 オブジェクトを DataSourceSelectArguments.Empty 渡します。

メソッドは Select() 、 を実装する オブジェクトを返します IEnumerable。 返される正確な型は、SqlDataSource コントロールの DataSourceMode プロパティの値によって異なります。 前のチュートリアルで説明したように、このプロパティは または DataReaderのいずれかのDataSet値に設定できます。 に設定すると DataSet、 メソッドは Select()DataView オブジェクトを返します。に設定すると DataReader、 を実装するオブジェクトが返されます IDataReaderRandomCategoryDataSource SqlDataSource のプロパティは DataSourceMode (既定値) にDataSet設定されているため、DataView オブジェクトを操作します。

次のコードは、SqlDataSource から DataView としてレコードを RandomCategoryDataSource 取得する方法と、最初の 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 表示されるメッセージを示しています。 もちろん、表示される実際のカテゴリ名は、ページにアクセスするたびに SqlDataSource によって RandomCategoryDataSource ランダムに選択されます (ポストバックを含む)。

ランダムに選択されたカテゴリの名前が表示されます

図 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 、イベント ハンドラーで SqlDataSource によって返される列値に CategoryID 基づいて値を RandomCategoryDataSource 設定する必要があるパラメーターがあります Page_Load

まず、ページに GridView を追加し、 という名前 ProductsByCategoryDataSourceの新しい SqlDataSource にバインドします。 手順 3 で行ったように、ストアド プロシージャを呼び出すように SqlDataSource を GetProductsByCategory 構成します。 [パラメーター ソース] ドロップダウン リストは [なし] のままにしますが、この既定値はプログラムで設定するため、既定値は入力しないでください。

[パラメーター ソース] が [なし] に設定されている [データ ソースの構成] ウィンドウを示すスクリーンショット。

図 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>

イベント ハンドラーでは、 パラメーターの をDefaultValueCategoryIDプログラムで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 で 、UPDATE、および DELETE ステートメントを定義INSERTする方法について説明します。 これらのステートメントが追加されたら、GridView、DetailsView、および FormView コントロールに固有の組み込みの挿入、編集、および削除機能を利用できます。

プログラミングに満足!

著者について

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

特別な感謝

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