適用対象: .NET Framework .NET
.NET Standard
ADO.NET の DataSet は、データ ソースに依存しない一貫したリレーショナル プログラミング モデルを提供するメモリ常駐型のデータ表現です。
DataSet はテーブル、制約、およびテーブル間のリレーションシップを含む完全なデータのセットを表します。
DataSet はデータ ソースとは独立しているため、 DataSet にはそのアプリケーションに固有のデータと複数のデータ ソースからのデータを含めることができます。 既存のデータ ソースとの対話は DataAdapterによって制御されます。
SelectCommand の DataAdapter プロパティは、データ ソースからデータを取得する Command オブジェクトです。
InsertCommandの UpdateCommand、 DeleteCommand 、 DataAdapter の各プロパティは、 Command のデータに対して行われた変更に基づいてデータ ソースのデータ更新を管理する DataSetオブジェクトです。 これらのプロパティは、「DataAdapter を使用してデータ ソースを更新する」で詳しく説明されています。
Fill の DataAdapter メソッドは、 DataSet の SelectCommand の結果を DataAdapterに設定するために使用します。
Fill は、その引数として、設定対象である DataSet と、 DataTable オブジェクト (つまり、 DataTable から返された行を格納する SelectCommandの名前) を受け取ります。
Note
DataAdapter を使用してテーブル全体を取得すると、特にテーブルの行数が多い場合は処理に時間がかかります。 データベースにアクセスし、データを検索して処理した後、そのデータをクライアントに転送するという時間のかかる処理が伴うためです。 また、テーブル全体をクライアントに取得しようとすると、サーバー上ですべての行がロックされます。
WHERE 句を使用して、クライアントから返される行数をできるだけ減らすことでパフォーマンスを向上させることができます。 また、 SELECT ステートメントで必要な列を明示的に指定するだけでもクライアントに返されるデータ量を減らすことができます。 それ以外の対策としては、一度に数百行など、行をバッチで取得し、クライアントが現在のバッチの処理を完了した時点で次のバッチを取得する方法も効果的です。
Fill メソッドは、 DataReader オブジェクトを暗黙的に使用して DataSet内でテーブルを作成するための列の名前と型、および DataSet内のテーブルの行を設定するためのデータを返します。 テーブルおよび列は、存在しない場合にのみ作成されます。それ以外の場合、 Fill には、既存の DataSet スキーマが使用されます。 列の型は、「ADO.NET でのデータ型のマッピング」のテーブルに従って、.NET Framework 型として作成されます。 データ ソースに主キーが存在し、DataAdapter.MissingSchemaAction が MissingSchemaAction.AddWithKey に設定されている場合だけ、主キーが作成されますが、それ以外の場合は主キーは作成されません。
Fill はテーブルに主キーがあることがわかると、主キー列の値がデータ ソースから返された主キー列の値と一致する行について、データ ソースから返されたデータで DataSet 内のデータを上書きします。 主キーが見つからない場合は、 DataSetのテーブルの末尾にデータを追加します。
Fill は DataSet の読み込み時に存在する可能性があるすべてのマッピングを使用します (「DataAdapter、DataTable、DataColumn のマッピング」を参照)。
Note
SelectCommand が OUTER JOIN の結果を返す場合、 DataAdapter は、生成される PrimaryKey に DataTable値を設定しません。 自分で PrimaryKey を定義して、重複行が正しく解決されるようにする必要があります。
次のコード サンプルでは、Microsoft SQL Server の SqlDataAdapter データベースへの SqlConnection を使用する Northwind のインスタンスを作成し、 DataTable 内の DataSet に顧客リストを読み込みます。
SqlConnection コンストラクターに渡される SQL ステートメントおよび SqlDataAdapter 引数は、 SelectCommand の SqlDataAdapterプロパティを作成するために使用されます。
例
// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
Note
このサンプル コードでは、 Connectionの開始と終了を明示的に行っていません。
Fill メソッドは、接続がまだ開いていないことを認識すると Connection が使用している DataAdapter を暗黙的に開きます。
Fill が接続を開いた場合は、 Fill の終了時に Fill が接続を終了します。 これにより、 Fill や Updateなどの単一の操作を扱う場合にコードを簡略化できます。 これに対し、開いている接続を必要とする複数の操作を実行する場合は、 Open の Connectionメソッドを明示的に呼び出し、データ ソースに対する操作の実行後に Close の Connectionメソッドを呼び出すことでアプリケーションのパフォーマンスを改善できます。 リソースを解放して他のクライアント アプリケーションが使用できるようにするために、データ ソースへの接続を開いたままにする時間は最小限にすることをお勧めします。
複数結果セット
DataAdapter は複数の結果セットを検出すると、 DataSetに複数のテーブルを作成します。 これらのテーブルには、Table0 のように、"Table" で始まるインクリメンタル既定名 TableNが割り当てられます。 テーブル名を引数として Fill メソッドに渡すと、TableName0 を表す "TableName" で始まるインクリメンタル既定名 TableNameNが割り当てられます。
複数の DataAdapter から DataSet を読み込む
1 つの DataAdapter で、任意の数の DataSet オブジェクトを使用できます。 それぞれの DataAdapter で 1 つ以上の DataTable オブジェクトにデータを格納し、関連するデータ ソースに更新を反映させることができます。
DataRelation に対して Constraint オブジェクトおよび DataSet オブジェクトを部分的に追加できるため、複数の異なるデータ ソースから取得したデータを関連付けることができます。 たとえば、Microsoft SQL Server データベース、OLE DB を介して公開される IBM Db2 データベース、および XML をストリーム転送するデータ ソースからのデータを DataSet に含めることができます。 1 つ以上の DataAdapter オブジェクトを使用して、各データ ソースとの通信を行うことができます。
例
次のコード サンプルでは、Microsoft SQL Server の Northwind データベースおよび Microsoft Access に格納された Northwind データベースから、それぞれ顧客リストと注文リストを取得します。 取得したテーブルを DataRelationで関連付けて、顧客および対応する注文の一覧を表示します。
// Assumes that customerConnection and orderConnection are valid SqlConnection objects.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", customerConnection);
SqlDataAdapter ordAdapter = new SqlDataAdapter(
"SELECT * FROM Orders", orderConnection);
DataSet customerOrders = new DataSet();
custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");
DataRelation relation = customerOrders.Relations.Add("CustOrders",
customerOrders.Tables["Customers"].Columns["CustomerID"],
customerOrders.Tables["Orders"].Columns["CustomerID"]);
foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
{
Console.WriteLine(pRow["CustomerID"]);
foreach (DataRow cRow in pRow.GetChildRows(relation))
Console.WriteLine("\t" + cRow["OrderID"]);
}
SQL Server Decimal 型
既定では、DataSet は .NET データ型を使用してデータを格納します。 ほとんどのアプリケーションで、これらのデータ型を使用してデータ ソース情報を簡単に表示できます。 しかし、データ ソースのデータ型が SQL Server の 10 進数データ型または数値データ型の場合は、この表現によって問題が生じる場合があります。 .NET decimal のデータ型の最大有効桁数は 28 桁であるのに対し、SQL Server decimal のデータ型の有効桁数は 38 桁です。
SqlDataAdapter が動作している間に、 Fill が、SQL Server の decimal フィールドの有効桁数が 28 文字を超えていると判断した場合、現在の行は DataTableに追加されません。 その場合は FillError イベントが発生するため、開発者は有効桁数の消失が発生していないかどうかを確認し、適切に対応できます。
FillError イベントの詳細については、「DataAdapter イベントの処理」を参照してください。 SQL Server の decimal 値を取得するために、 SqlDataReader オブジェクトを使用し、 GetSqlDecimal メソッドを呼び出すこともできます。
ADO.NET でも System.Data.SqlTypes の DataSet に対するサポート機能が強化されています。 詳細については、「 SqlTypes and the DataSet」を参照してください。