次の方法で共有


DataAdapter からの DataSet の読み込み

ADO.NET の DataSet は、データ ソースに依存しない一貫したリレーショナル プログラミング モデルを提供する、メモリ常駐するデータの表現形式です。DataSet はテーブル、制約、およびテーブル間のリレーションシップを含む完全なデータのセットを表します。DataSet はデータ ソースとは独立しているため、DataSet にはそのアプリケーションに固有のデータと複数のデータ ソースからのデータを含めることができます。既存のデータ ソースとの対話は DataAdapter によって制御されます。

.NET Framework に含まれている各 .NET Framework データ プロバイダは、DataAdapter オブジェクトを持っています。.NET Framework Data Provider for OLE DB には OleDbDataAdapter オブジェクト、.NET Framework Data Provider for SQL Server には SqlDataAdapter オブジェクト、.NET Framework Data Provider for ODBC には OdbcDataAdapter オブジェクトがあります。DataAdapter は、データ ソースからデータを取得し、1 つの DataSet 内でテーブルを設定するために使用されます。また、DataAdapter は、DataSet に対して加えられた変更をデータ ソースに反映させます。DataAdapter は .NET Framework データ プロバイダの Connection オブジェクトを使用してデータ ソースに接続し、Command オブジェクトを使用してデータ ソースからデータを取得し、変更をデータ ソースに反映させます。

DataAdapterSelectCommand プロパティは、データ ソースからデータを取得する Command オブジェクトです。DataAdapterInsertCommandUpdateCommandDeleteCommand の各プロパティは、DataSet のデータに対して行われた変更に基づいてデータ ソースのデータ更新を管理する Command オブジェクトです。これらのプロパティについては、「DataAdapter および DataSet によるデータベースの更新」でさらに詳しく説明します。

DataAdapterFill メソッドは、DataAdapterSelectCommand の結果を使用して DataSet を設定するために使用します。Fill は、自らの引数として、設定対象である DataSet と、DataTable オブジェクト (つまり、SelectCommand が返した行を格納している DataTable の名前) を受け取ります。

Fill メソッドは、DataReader オブジェクトを暗黙的に使用して DataSet 内でテーブルを作成するための列の名前と型、および DataSet 内のテーブルの行を設定するためのデータを返します。テーブルおよび列は、存在しない場合にだけ作成されます。既に存在する場合は、Fill は既存の DataSet スキーマを使用します。列の型は、「.NET Framework データ プロバイダのデータ型から .NET Framework のデータ型への変換」の表に基づき .NET Framework の型として作成されます。データ ソースに主キーが存在し、DataAdapter.MissingSchemaActionMissingSchemaAction.AddWithKey に設定されている場合だけ、主キーが作成されますが、それ以外の場合は主キーは作成されません。Fill はテーブルに主キーがあることがわかると、主キー列の値がデータ ソースから返された主キー列の値と一致する行について DataSet 内のデータをデータ ソースから返されたデータで上書きします。主キーが見つからない場合は、DataSet のテーブルの末尾にデータを追加します。FillDataSet にデータを読み込むときに存在するすべての TableMappings を使用します (「DataTable と DataColumn のマップの設定」を参照してください)。

メモ   SelectCommand が OUTER JOIN の結果を返す場合、DataAdapter は、生成される DataTablePrimaryKey 値を設定しません。自分で PrimaryKey を定義して、重複行が正しく反映されるようにする必要があります。詳細については、「テーブルの主キーの定義」を参照してください。

Microsoft SQL Server Northwind データベースへの Connection を使用し DataSet 内の DataTable に顧客リストを読み込む DataAdapter のインスタンスを作成するサンプル コードを次に示します。DataAdapter コンストラクタに渡される SQL ステートメントおよび Connection 引数は、DataAdapterSelectCommand プロパティを作成するために使用されます。

SqlClient

Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")

Dim selectCMD As SqlCommand = New SqlCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn)
selectCMD.CommandTimeout = 30

Dim custDA As SqlDataAdapter = New SqlDataAdapter
custDA.SelectCommand = selectCMD

nwindConn.Open()

Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")

nwindConn.Close()
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");

SqlCommand selectCMD = new SqlCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn);
selectCMD.CommandTimeout = 30;

SqlDataAdapter custDA = new SqlDataAdapter();
custDA.SelectCommand = selectCMD;

nwindConn.Open();

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

nwindConn.Close();

OleDb

Dim nwindConn As OleDbConnection = New OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;" & _
                                                       "Integrated Security=SSPI;Initial Catalog=northwind")

Dim selectCMD As OleDbCommand = New OleDbCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn)
selectCMD.CommandTimeout = 30

Dim custDA As OleDbDataAdapter = New OleDbDataAdapter
custDA.SelectCommand = selectCMD

Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")
[C#]
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;" +
                                                "Integrated Security=SSPI;Initial Catalog=northwind");

OleDbCommand selectCMD = new OleDbCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn);
selectCMD.CommandTimeout = 30;

OleDbDataAdapter custDA = new OleDbDataAdapter();
custDA.SelectCommand = selectCMD;

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

Odbc

Dim nwindConn As OdbcConnection = New OdbcConnection("Driver={SQL Server};Server=localhost;" & _
                                                     "Trusted_Connection=yes;Database=northwind")

Dim selectCMD As OdbcCommand = New OdbcCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn)
selectCMD.CommandTimeout = 30

Dim custDA As OdbcDataAdapter = New OdbcDataAdapter
custDA.SelectCommand = selectCMD

nwindConn.Open()

Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")

nwindConn.Close()
[C#]
OdbcConnection nwindConn = new OdbcConnection("Driver={SQL Server};Server=localhost;" +
                                              "Trusted_Connection=yes;Database=northwind");

OdbcCommand selectCMD = new OdbcCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn);
selectCMD.CommandTimeout = 30;

OdbcDataAdapter custDA = new OdbcDataAdapter();
custDA.SelectCommand = selectCMD;

nwindConn.Open();

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

nwindConn.Close();

このコードは Connection の開始と終了を明示的に行っているわけではないことに注意してください。Fill メソッドは、接続がまだ開いていないことを認識すると DataAdapter が使用している Connection を暗黙的に開きます。Fill が接続を開いた場合は、Fill の終了時に Fill が接続を終了します。これにより、FillUpdate などの単一の操作を扱う場合にコードを簡略化できます。これに対し、開いている接続を必要とする複数の操作を実行する場合は、ConnectionOpen メソッドを明示的に呼び出し、データ ソースに対する操作の実行後に ConnectionClose メソッドを呼び出すことでアプリケーションのパフォーマンスを改善できます。他のクライアント アプリケーションが使用するリソースを最短時間で解放するには、データ ソースへの接続は開いたままにしておくことをお勧めします。

複数結果セット

DataAdapter は複数の結果セットを検出すると、DataSet に複数のテーブルを作成します。これらのテーブルには、Table0 のように、"Table" で始まるインクリメンタル既定名 TableN が割り当てられます。テーブル名を引数として Fill メソッドに渡すと、TableName0 を表す "TableName" で始まるインクリメンタルな既定の名前 TableNameN が割り当てられます。

複数の DataAdapter からの DataSet の読み込み

1 つの DataSet に対して任意の数の DataAdapter を使用できます。それぞれの DataAdapter で 1 つ以上の DataTable オブジェクトにデータを格納し、関連するデータ ソースに更新を反映させることができます。DataSet に対して、DataRelation オブジェクトおよび Constraint オブジェクトをローカルで追加できるため、開発者は種類の異なる複数のデータ ソースから得られたデータを関連付けることができます。たとえば、Microsoft SQL Server データベース、OLE DB を通じて公開される IBM DB2 データベース、および XML をストリーム転送するデータ ソースからのデータを DataSet に含めることができます。1 つ以上の DataAdapter オブジェクトを使用して、各データ ソースとの通信を行うことができます。

次のサンプル コードは、Microsoft SQL Server 2000 の Northwind データベースからの顧客リストと Microsoft® Access 2000 に格納されている Northwind データベースからのオーダー リストを取得します。データが格納されているテーブルが DataRelation に関連付けられ、顧客リストが各顧客のオーダーと共に表示されます。DataRelation オブジェクトの詳細については、「テーブル間のリレーションシップの追加」および「テーブル間のリレーションシップの移動」を参照してください。

Dim custConn As SqlConnection= New SqlConnection("Data Source=localhost;Integrated Security=SSPI;" & _
                                                 "Initial Catalog=northwind;")
Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", custConn)

Dim orderConn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
                                                       "Data Source=c:\Program Files\Microsoft Office\" & _
                                                       "Office\Samples\northwind.mdb;")
Dim orderDA As OleDbDataAdapter = New OleDbDataAdapter("SELECT * FROM Orders", orderConn)

custConn.Open()
orderConn.Open()

Dim custDS As DataSet = New DataSet()

custDA.Fill(custDS, "Customers")
orderDA.Fill(custDS, "Orders")

custConn.Close()
orderConn.Close()

Dim custOrderRel As DataRelation = custDS.Relations.Add("CustOrders", _
                                     custDS.Tables("Customers").Columns("CustomerID"), _ 
                                     custDS.Tables("Orders").Columns("CustomerID"))

Dim pRow, cRow As DataRow

For Each pRow In custDS.Tables("Customers").Rows
  Console.WriteLine(pRow("CustomerID").ToString())

  For Each cRow In pRow.GetChildRows(custOrderRel)
    Console.WriteLine(vbTab & cRow("OrderID").ToString())
  Next
Next 
[C#]
SqlConnection custConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind;");
SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn);

OleDbConnection orderConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" +
                                                "Data Source=c:\\Program Files\\Microsoft Office\\Office\\Samples\\northwind.mdb;");
OleDbDataAdapter orderDA = new OleDbDataAdapter("SELECT * FROM Orders", orderConn);

custConn.Open();
orderConn.Open();

DataSet custDS = new DataSet();

custDA.Fill(custDS, "Customers");
orderDA.Fill(custDS, "Orders");

custConn.Close();
orderConn.Close();

DataRelation custOrderRel = custDS.Relations.Add("CustOrders",
                              custDS.Tables["Customers"].Columns["CustomerID"],    
                              custDS.Tables["Orders"].Columns["CustomerID"]);

foreach (DataRow pRow in custDS.Tables["Customers"].Rows)
{
  Console.WriteLine(pRow["CustomerID"]);
   foreach (DataRow cRow in pRow.GetChildRows(custOrderRel))
    Console.WriteLine("\t" + cRow["OrderID"]);
}

SQL Server の 10 進数型

DataSet は、.NET Framework のデータ型を使用してデータを格納します。ほとんどのアプリケーションで、これらのデータ型を使用してデータ ソース情報を簡単に表示できます。しかし、データ ソースのデータ型が SQL Server の decimal の場合は、この表現によって問題が生じる場合があります。.NET Framework の decimal データ型の許容最大有効桁数は 28 桁であるのに対し、SQL Server の decimal データ型の許容最大有効桁数は 38 桁です。Fill が動作している間に、SqlDataAdapter が、SQL Server の decimal フィールドの有効桁数が 28 文字を超えていると判断した場合、現在の行は DataTable に追加されません。その場合は FillError イベントが発生するため、開発者は有効桁数の消失が発生していないかどうかを確認し、適切に対応できます。FillError イベントの詳細については、「DataAdapter イベントの使用」を参照してください。SQL Server の decimal 値を取得するには、SqlDataReader オブジェクトを使用し、GetSqlDecimal メソッドを呼び出すこともできます。

OLE DB のチャプタ

階層構造の行セット、つまりチャプタ (OLE DB では DBTYPE_HCHAPTER 型、ADO では adChapter 型) を使用して DataSet の内容を格納できます。DataAdapterFill が動作している間にチャプタ列を検出すると、そのチャプタ列のための DataTable を作成し、チャプタからの列を行が格納します。チャプタ列用に作成されたテーブルには、親テーブルの名前とチャプタ列の名前の両方を使用して "ParentTableNameChapteredColumnName" 形式の名前が割り当てられます。DataSet にチャプタ列の名前と一致するテーブルが既に存在する場合は、現在のテーブルにチャプタ データが格納されます。既存のテーブルにチャプタ内の列と一致する列が存在しない場合は、新しい列が追加されます。

DataSet 内のテーブルにチャプタ列のデータを格納する前に、親テーブルと子テーブルの両方に 1 つの整数列を追加し、親列を自動インクリメントに設定し、両方のテーブルに追加された列を使用して DataRelation を作成すると、階層行セットを形成している親テーブルと子テーブルの間にリレーションシップが作成されます。追加されたリレーションシップには親テーブルの名前とチャプタ列の名前を使用して "ParentTableNameChapterColumnName" 形式の名前が割り当てられます。

関連付けられた列は、DataSet だけに存在します。それ以降に、そのデータ ソースから Fill 操作を実行すると、変更を既存の行にマージするのではなく、テーブルに新しい行が追加されます。

DataTable を受け取る DataAdapter.Fill オーバーロードを使用した場合は、そのテーブルだけにデータが格納されます。自動インクリメント整数列は、引き続きそのテーブルに追加されますが、子テーブルの作成、子テーブルへのデータの格納、およびリレーションシップの作成は行われません。

MSDataShape プロバイダを使用して顧客リスト内の各顧客に対応するオーダー列を生成する例を次に示します。チャプタ列を生成した後で、1 つの DataSet 内にそのデータを格納します。

Dim nwindConn As OleDbConnection = New OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" & _
                                         "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")

Dim custDA As OleDbDataAdapter = New OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " & _
                                      "  APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " & _
                                      "  RELATE CustomerID TO CustomerID)", nwindConn)

Dim custDS As DataSet = New DataSet()

custDA.Fill(custDS, "Customers")
[C#]
OleDbConnection nwindConn = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
                                  "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");

OleDbDataAdapter custDA = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
                                      "  APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +
                                      "  RELATE CustomerID TO CustomerID)", nwindConn);

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

Fill 操作が完了すると、DataSetCustomersCustomersOrders の 2 つのテーブルが格納されます。CustomersOrders はチャプタ列を表します。Orders という付加的な列が Customers テーブルに追加され、CustomersOrders という付加的な列が CustomersOrders テーブルに追加されます。Customers テーブルの Orders 列は、自動インクリメントに設定されます。Customers を親テーブルとするテーブルに追加された列を使用して、DataRelation CustomersOrders が作成されます。サンプル結果の一部を次の表に示します。

TableName: Customers

CustomerID CompanyName Orders
ALFKI Alfreds Futterkiste 0
ANATR Ana Trujillo Emparedados y helados 1

TableName: CustomersOrders

CustomerID OrderID CustomersOrders
ALFKI 10643 0
ALFKI 10692 0
ANATR 10308 1
ANATR 10625 1

参照

.NET Framework データ プロバイダによるデータのアクセス | .NET Framework データ プロバイダのデータ型から .NET Framework のデータ型への変換 | DataSet クラス | DataTable クラス | OleDbCommand クラス| OleDbConnection クラス | OleDbDataAdapter クラス | OdbcCommand クラス | OdbcConnection クラス | OdbcDataAdapter クラス | SqlCommand クラス | SqlConnection クラス | SqlDataAdapter クラス