DataAdapter から DataSet を設定する
適用対象: .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");
注意
このサンプル コードでは、 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 つの DataSet
で、任意の数の DataAdapter
オブジェクトを使用できます。 それぞれの 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 でも DataSet
の System.Data.SqlTypes に対するサポート機能が強化されています。 詳細については、「 SqlTypes and the DataSet」を参照してください。