DataSet に既存の制約を追加する
適用対象: .NET Framework .NET .NET Standard
SqlDataAdapter の Fill メソッドを使うと、DataSet にデータ ソースからのテーブルの列および行だけが格納されます。制約は一般にデータ ソースで設定されますが、既定では Fill メソッドによって DataSet にこのスキーマ情報は追加されません。
データ ソースからの既存の主キー制約情報を DataSet に設定するには、DataAdapter の FillSchema メソッドを呼び出すか、または Fill を呼び出す前に DataAdapter の MissingSchemaAction プロパティを AddWithKey に設定します。 これにより、データ ソースの主キー制約が DataSet の主キー制約に反映されます。
注意
外部キー制約情報はインクルードされないため、明示的に作成する必要があります。
データを格納する前に DataSet にスキーマ情報を追加すると、DataSet 内の DataTable オブジェクトに主キー制約が含まれるようになります。 その結果、DataSet に対して格納を行う追加の呼び出しを行うと、主キー列の情報を使用して、データ ソースからの新しい行と、各 DataTable の現在の行が照合されて、テーブルの現在のデータがデータ ソースのデータで上書きされます。 スキーマ情報がないと、DataSet にデータ ソースからの新しい行が付け加えられ、重複行が発生します。
Note
データ ソースの列が自動インクリメントとして指定されている場合、FillSchema メソッドまたは MissingSchemaAction が AddWithKey に設定された Fill メソッドでは、AutoIncrement プロパティが true
に設定された DataColumn が作成されます。 ただし、AutoIncrementStep 値と AutoIncrementSeed 値は開発者自身が明示的に設定する必要があります。
注意
FillSchema を使用したり、MissingSchemaAction を AddWithKey に設定したりすると、データ ソースで主キー列情報を確認するための追加の処理が必要になります。 この追加の処理によりパフォーマンスが低下する場合があります。 デザイン時に主キー情報がわかっている場合は、最適のパフォーマンスを得るために主キー列 (複数の場合もある) を明示的に指定することをお勧めします。
次のコード例では、FillSchema を使用して DataSet にスキーマ情報を追加する方法を示します。
// 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");
MissingSchemaAction プロパティと Fill メソッドを使用して、DataSet にスキーマ情報を追加する方法を次のコード サンプルに示します。
// 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"]);
}
複数の結果セットの処理
DataAdapter が SelectCommand から返された複数の結果セットに一致する場合、DataSet に複数のテーブルが作成されます。 テーブルには、Table N という既定の名前が設定されます。N は 0 から始まりインクリメントされますが、"Table0" ではなく Table から始まります。 テーブル名が FillSchema メソッドに引数として渡されると、0 からから始まるインクリメンタル名 TableName N が割り当てられます。ここでは、"TableName0" ではなく TableName から始まります。