単一行エンティティを返すデータ操作

Priya Singh
Microsoft Developer Network

2001 年 5 月

要約: この記事では、ADO.NET を使用して単一行エンティティを返すデータ操作について説明します。これは、Microsoft .NET Framework SDK および Visual Studio.NET のベータ 1 に準拠します。

「.NET による分散アプリケーションの構築」の完全なサンプル コードは、MSDN Online Code Center からダウンロードまたは参照してください。

この記事で説明されている例を確認するには、直接、BDAdotNetData2.vb をご覧ください。

「.NET による分散アプリケーションの構築」のサンプル コードをダウンロードする。(50 KB)

目次

  • はじめに

  • データを返す操作

    • Output パラメータを使用する
    • ADO.NET DataReader オブジェクトを使用する
    • ADO.NET DataSet オブジェクトを使用する
  • 書き込み操作

    • ADO.NET Command オブジェクトを使用する
    • ADO.NET DataSetCommand オブジェクトを使用する
  • 結論

  • はじめに

    ADO.NET は、単一行データ エンティティを返すクエリを実行し、そのデータを変更するための様々な手段を提供します。この記事では、ADO.NET SQL マネージド プロバイダを使用したデータ変換などの手段について解説します。

  • データを返す操作

    SQL 式の中の SELECT ステートメントからのデータは、ADO.NET Command オブジェクトの Output パラメータ、DataReader オブジェクト、または DataSet オブジェクトを使用して返すことができます。

    • Output パラメータを使用する

      Output パラメータ付きのストアド プロシージャは、クエリを実行する手段としてだけでなく、単一行データ エンティティを返す手段としても効率的です。Output パラメータを扱うには、ADO.NET Command オブジェクトのパラメータ コレクションを使用します。

      次の例では、ストアド プロシージャのパラメータが Command オブジェクトの Parameters コレクションで定義されています。このストアド プロシージャは、Input パラメータ "@OrderId"、また、指定された注文のステータスを返す Output パラメータ "@OrderStatus" を定義しています。


  
Dim sqlConn As SQLConnection
Dim sqlCmd As SQLCommand
Dim param As SQLParameter
Try
   ' connection オブジェクトを生成する
   sqlConn = New SQLConnection(myConnString)
   ' command オブジェクトを生成する
   sqlCmd = New SQLCommand()
   ' 接続とストアドプロシージャを定義する
   With sqlCmd
      .CommandType = CommandType.StoredProcedure
      .CommandText = "GetOrderStatus"
      .ActiveConnection = sqlConn
   End With
   ' parameter コレクションに input パラメータを定義、追加する
   param = SQLCmd.Parameters.Add(New _ SQLParameter("@OrderId", _
      SQLDataType.Int))
   With param
      ' パラメータの動きを明示する
      .Direction = ParameterDirection.Input
      ' パラメータの値を設定する
      .Value = 1
   End with
   ' parameter コレクションに input パラメータを定義、追加する
   param = SQLCmd.Parameters.Add(New _
      SQLParameter("@OrderStatus", _
      SQLDataType.Int))
   ' パラメータの動きを明示する
   param.Direction = ParameterDirection.Output
   ' 接続を開く
   SQLConn.Open()
   ' コマンドを実行する
   sqlCmd.Execute()
   ' 返されたデータに対しての処理を行う
   orderStatus = sqlCmd.Parameters("@OrderStatus").Value.ToString
   …
Catch e As Exception
   ' 例外の処理
   …
Finally
   ' 接続を閉じる
   sqlConn.Close()
End Try

完全な BDAdotNetData2.vb サンプル コードの例 1 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

  - **ADO.NET DataReader オブジェクトを使用する**  
      
    *Output* パラメータの欠点は、SQL Server データベースの場合はストアド プロシージャ、.mdb データベースの場合はパラメータ クエリなど、データベース上に対応するアプリケーション コードを必要とすることです。ADO.NET **DataReader** は、ストアド プロシージャだけでなく、アドホックな SQL クエリからもデータを返すことができます。**DataReader** オブジェクトは、読み取り専用、前方専用のデータ ストリームを返します。
    
    次の例では、クエリは、CustomerId が 1 である顧客が行った注文のうち、OrderId 1 の注文を含んでいる単一の行を返します。
    
    

  
Dim sqlConn As SQLConnection
Dim sqlCmd As SQLCommand
Dim rowReader As SQLDataReader
…
Try
   ' connection オブジェクトを生成
   SqlConn = New SQLConnection(myConnString)
   ' command オブジェクトを生成
   SqlCmd = New SQLCommand()
   ' 実行させるコマンドを明示する
   With sqlCmd
      .CommandType = CommandType.Text
      .CommandText = "Exec GetOrderHeader @OrderId=1"
      .ActiveConnection = sqlConn
   End With
   ' 接続を開く
   sqlConn.Open()
   ' コマンドを実行する
   sqlCmd.Execute(rowReader)
   ' 行の位置を特定する
   rowReader.Read()
   ' 返された行に対しての処理
   outString = rowReader.Item("OrderId").ToString() & "," & _
      rowReader.Item("CustomerId").ToString() & "," & _
      rowReader.Item("OrderStatus").ToString() & "," & _
      rowReader.Item("OrderDate").ToString()
Catch e As Exception
   ' 例外の処理
   …
Finally
   ' DataReader を閉じる
   rowReader.Close()
   ' 接続を閉じる
   sqlConn.Close()
End Try

完全な BDAdotNetData2.vb サンプル コードの例 2 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

  - **ADO.NET DataSet オブジェクトを使用する**  
      
    **DataSet** オブジェクトは、Microsoft<sup>®</sup> .NET<sup>™</sup> Framework によって提供される主要な非接続状態でのデータ コンテナです。これは高度なキャッシュであり、SQL および ADO マネージド プロバイダとともに、データ ソースからのデータの読み取りと、変更後のデータのデータ ソースへの書き戻しをサポートします。**DataSet** モデルは、関連する複数のデータ テーブルをサポートするので、単一行データ エンティティで多くの **DataSet** 機能を使用することはありません。しかし、単一行データ エンティティではこれらの機能を駆使する必要がないにもかかわらず、**DataSet** オブジェクトは、単一行データ エンティティの場合でも考慮すべき便利なコンテナです。
    
    **DataSetCommand** オブジェクトは、データ ソースと **DataSet** オブジェクトの間のマッピング層の役目を果たします。データ ソースからデータを取得し、**DataSet** オブジェクトに汎化して、変更をデータ ソースに送り返します。
    
    次の例では、クエリは、CustomerId が 1 である顧客が行った注文のうち、OrderId 1 の注文を含んでいる単一の行を返します。
    
    

  
Dim sqlDSCmd As New System.Data.SQL.SQLDataSetCommand()
Dim resultDataSet As New DataSet()
Try
   ' 接続と実行されるクエリを明示する
   With sqlDSCmd
      With .SelectCommand
		.CommandType = CommandType.Text
		.CommandText = "Exec GetOrderHeader @OrderId=1"
		.ActiveConnection = New _
            System.Data.SQL.SQLConnection(myConnString)
      End With
   ' 返されたデータによって DataSet を生成する
		.FillDataSet(resultDataSet, "Order")
   End With
   colItemName =_
      resultDataSet.Tables("Order").Rows(0).Item("ShipToName").ToString()
   …
Catch E As Exception
   ' 例外を処理する
   …
End Try

完全な BDAdotNetData2.vb サンプル コードの例 3 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

  • 書き込み操作

    ADO.NET オブジェクトを使用すると、単一行の変更とデータ ソースへの返送を簡単に行うことができます。書き込み操作のための最も単純な技法は、Command オブジェクトを使用して、アドホックな SQL またはストアド プロシージャを実行することです。DataSet コマンドは、より多くの機能を持ち、データが DataSet オブジェクトに取得されている場合は特に便利です。

    • ADO.NET Command オブジェクトを使用する

      ADO.NET Command オブジェクトを使用したアドホックな SQL またはストアド プロシージャの実行については、「行を返さないデータ操作」で説明されています。

    • ADO.NET DataSetCommand オブジェクトを使用する

      DataSetCommand オブジェクトは、データ ソースへの接続、データの取得、および DataSet オブジェクトへのデータのポピュレートのために使用されます。DataSet オブジェクト内のデータは、変更することができます。DataSetCommand は、DataSet オブジェクトでの変更をデータ ソースと調整します。

      DataSet オブジェクトを使用する

      DataSetCommand オブジェクトの Update メソッドは、DataSet オブジェクトにキャッシュされた変更をデータ ソースにサブミットします。DataSetCommand オブジェクトは、新しい行をサブミットするには InsertCommand を、変更された行をサブミットするには UpdateCommand を、データベースから行を削除するには DeleteCommand を使用します。

      DataSetCommand オブジェクトの InsertCommandUpdateCommand、または DeleteCommand プロパティを指定した場合、Update メソッドは、DataSet オブジェクト内の挿入、更新、または削除された行のそれぞれについて、InsertUpdate、または Delete コマンドを実行します。そうでない場合は、Update メソッドは ForceGenerateUpdate というメソッドを呼び出して、InsertUpdate、および Delete コマンドを自動生成します。Update メソッドを呼び出すと、DataSetCommand オブジェクトは変更された行を調べて、その行の保留中の変更をサブミットするために、どの DataCommand オブジェクトを実行するかを判断します。

      望ましいのは、独自の InsertCommandDeleteCommand、または UpdateCommand を完全に指定することです。そうすれば、更新方法を明示的に制御することができ、自動生成よりもパフォーマンスが向上します。

      この記事では、変更によってデータ ソースを更新するために使用される自動生成されたコマンドだけを取り上げます。独自の InsertUpdate、および Delete コマンドの指定については、「行のセットに対するデータ操作」を参照してください。

      自動生成された Insert コマンド

      DataSetCommand オブジェクトに対して Update メソッドを呼び出すと、InsertCommand プロパティが設定されていなかった場合、Update メソッドは指定された Select コマンドに基づいて Insert コマンドを自動生成します。

      次のコード例では、DataSet オブジェクトに、注文を含んでいる単一行がポピュレートされます。DataSet オブジェクトに新しい 1 行を追加します。それがデータ ソース内のテーブルに挿入されます。


  
Dim sqlDSCmd As New System.Data.SQL.SQLDataSetCommand()
Dim resultDataSet As New DataSet()
Dim workRow As DataRow
Try
   ' select コマンドを明示する
   With sqlDSCmd
      With .SelectCommand
         ' 実行するコマンドのタイプと必要なコマンド文字列をセットする
         .CommandType = CommandType.Text
         .CommandText = "Exec GetOrderHeader @OrderId=-1"
         .ActiveConnection = New _
            System.Data.SQL.SQLConnection(myConnString)
      End With
      ' 返されたデータと共に DateSet を取得する
      .FillDataSet(resultDataSet, "Order")
   End With
   ' 新しい行を作る
   workRow = resultDataSet.Tables("Order").NewRow
   ' 作業用の行にデータをセットする
   workRow.Item("CustomerId") = 1
   workRow.Item("OrderDate") = Now()
   workRow.Item("ShipToName") = "Resident "
   workRow.Item("ShipToAddressId") = 1
   workRow.Item("OrderStatus") = 400
   ' DataSetへ行を追加する
   resultDataSet.Tables("Order").Rows.Add(workRow)
   ' データソースと共に変更を反映させる
   sqlDSCmd.Update(resultDataSet, "Order")
Catch E As Exception
   ' 例外の処理
   …
End Try

完全な BDAdotNetData2.vb サンプル コードの例 4 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

    **自動生成された Update コマンド**  
      
    **DataSetCommand** オブジェクトに対して **Update** メソッドを呼び出すと、**UpdateCommand** プロパティが設定されていなかった場合、**Update** メソッドは指定された **Select** コマンドに基づいて **Update** コマンドを自動生成します。
    
    次のコード例では、**DataSet** オブジェクトに、注文を含んでいる単一行がポピュレートされます。**DataSet** オブジェクト内の行を更新します。最後に、**DataSetCommand** オブジェクトが変更をデータ ソースに送り返します。
    
    

  
Dim sqlDSCmd As New System.Data.SQL.SQLDataSetCommand()
Dim resultDataSet As New DataSet()
Try
   ' Select コマンドを明示する
   With sqlDSCmd
      With .SelectCommand
         .CommandType = CommandType.Text

         .CommandText = " Exec GetOrderHeader @OrderId=1"
         .ActiveConnection = New _
            System.Data.SQL.SQLConnection(myConnString)
      End With
      ' 返されたデータと共に DataSet を取得する
      .FillDataSet(resultDataSet, "Order")
   End With
   ' 行を更新する
   resultDataSet.Tables("Order").Rows(0).Item("ShipToName") =_
      "NewResident"
   ' 変更を反映させる
   sqlDSCmd.Update(resultDataSet, "Order")
Catch E As Exception
   ' 例外の処理
   …
End Try

完全な BDAdotNetData2.vb サンプル コードの例 5 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

    **自動生成された Delete コマンド**  
      
    **DataSetCommand** オブジェクトに対して **Update** メソッドを呼び出すと、**DeleteCommand** プロパティが設定されていなかった場合、**Update** メソッドは指定された **Select** コマンドに基づいて **Delete** コマンドを自動生成します。
    
    次のコード例では、**DataSet** オブジェクトに、注文を含んでいる単一行がポピュレートされます。**DataSet** オブジェクト内の行を削除します。最後に、**DataSetCommand** オブジェクトがデータベースを更新します。
    
    

  
Dim sqlDSCmd As New System.Data.SQL.SQLDataSetCommand()
Dim resultDataSet As New DataSet()
Dim workRow As DataRow
Try
   ' select コマンドを明示する
   With sqlDSCmd
      With .SelectCommand
         .CommandType = CommandType.Text
         .CommandText = " Exec GetOrderHeader @OrderId=1"
         .ActiveConnection = New _
            System.Data.SQL.SQLConnection(myConnString)
      End With
      ' 返されたデータと共に DataSet を取得する
      .FillDataSet(resultDataSet, "Order")
   End With
   ' DataSet の Order テーブルから行を取得する
   resultDataSet.Tables("Order").Rows(0).Delete()
   ' データソースに変更を反映させる
   sqlDSCmd.Update(resultDataSet, "Order")
Catch E As Exception
   ' 例外の処理
   …
End Try

完全な BDAdotNetData2.vb サンプル コードの例 6 を参照してください (ダウンロードについては、この記事の始めを参照してください)。

  • 結論

    ADO.NET は、単一行データ エンティティの読み取りと書き込みに便利な様々な機能を提供します。最も適切な方法を選択するには、データ ソースに対して実行される操作だけでなく、アプリケーション内のデータの表現も考慮する必要があります。Input および Output パラメータまたは DataReader オブジェクトは軽量であり、パフォーマンスの点で優れています。一方、DataSet オブジェクトは、便利なデータ コンテナとしての機能と高度な機能を併せ持っています。