.NET Framework アプリケーションでデータセット間のリレーションシップを作成する
Note
データセットと関連クラスは、アプリケーションがデータベースから切断されている間にアプリケーションがメモリ内のデータを操作できるようにする、2000 年代初期からのレガシ .NET Framework テクノロジです。 テクノロジが特に役立つのは、ユーザーがデータを変更し、変更をデータベースに戻して保持できるようにするアプリケーションです。 データセットは非常に優れたテクノロジであることが証明されていますが、新しい .NET アプリケーションでは Entity Framework Core を使用することをお勧めしています。 Entity Framework には、オブジェクト モデルとして表形式データを操作する、より自然な方法が用意されており、よりシンプルなプログラミング インターフェイスが備わっています。
関連するデータ テーブルが含まれるデータセットでは、テーブル間の親子関係を表し、相互に関連するレコードを返すために、DataRelation オブジェクトが使用されます。 データ ソース構成ウィザードまたはデータセット デザイナーを使用して、関連するテーブルをデータセットに追加すると、DataRelation オブジェクトが自動的に作成および構成されます。
DataRelation オブジェクトにより、次の 2 つの機能が実行されます。
ユーザーが作業しているレコードに関連するレコードを利用できるようにします。 ユーザーが親レコードを使用している場合は子レコードが提供され (GetChildRows)、子レコードを使用している場合は親レコードが提供されます (GetParentRow)。
参照整合性の制約を適用できます (たとえば、親レコードを削除すると、関連する子レコードが削除されます)。
真の結合と、DataRelation オブジェクトの関数の違いを理解しておくことが重要です。 真の結合では、親テーブルと子テーブルからレコードが取得され、1 つのフラット レコードセットに格納されます。 DataRelation オブジェクトを使用すると、新しいレコードセットは作成されません。 代わりに、DataRelation によってテーブル間のリレーションシップが追跡され、親レコードと子レコードの同期が維持されます。
DataRelation のオブジェクトと制約
DataRelation オブジェクトは、次の制約を作成して適用するためにも使用されます。
一意制約。テーブル内の列に重複が含まれていないことが保証されます。
外部キー制約。データセット内の親テーブルと子テーブルの間の参照整合性を維持するために使用できます。
DataRelation オブジェクトで指定する制約は、自動的に適切なオブジェクトを作成するか、プロパティを設定することによって実装されます。 DataRelation オブジェクトを使用して外部キー制約を作成すると、ForeignKeyConstraint クラスのインスタンスが DataRelation オブジェクトの ChildKeyConstraint プロパティに追加されます。
一意制約は、単にデータ列の Unique プロパティを true
に設定することによって、または UniqueConstraint クラスのインスタンスを DataRelation オブジェクトの ParentKeyConstraint プロパティに追加することによって、実装されます。 データセットの制約を中断する方法の詳細については、「データセットの読み込み中に制約をオフにする」を参照してください。
参照整合性の規則
外部キー制約の一部として、次の 3 つのタイミングで適用される参照整合性規則を指定できます。
親レコードが更新されたとき
親レコードが削除されたとき
変更が受け入れられるか拒否されたとき
作成できる規則は、Rule 列挙型で指定されています。次の表にそれを示します。
外部キー制約の規則 | アクション |
---|---|
Cascade | 親レコードに対して行われた変更 (更新または削除) が、子テーブルの関連レコードでも行われます。 |
SetNull | 子レコードは削除されませんが、子レコードの外部キーは DBNull に設定されます。 この設定では、子レコードを "孤立" として残すことができます。つまり、それらは親レコードとのリレーションシップがありません。 注: この規則を使用すると、子テーブルに無効なデータが発生する可能性があります。 |
SetDefault | 関連する子レコードの外部キーは、(列の DefaultValue プロパティによって設定される) 既定値に設定されます。 |
None | 関連する子レコードは変更されません。 この設定では、子レコードに無効な親レコードへの参照を含めることができます。 |
データセットのテーブルの更新について詳しくは、「データをデータベースに保存する」を参照してください。
制約のみのリレーションシップ
DataRelation オブジェクトを作成するときに、制約を適用するためにのみリレーションシップを使用することを指定できます。つまり、関連するレコードへのアクセスには使用されません。 このオプションを使用すると、関連レコード機能を持つものより、少しだけ効率的で、含まれるメソッドが少ないデータセットを生成できます。 ただし、関連するレコードにアクセスすることはできません。 たとえば、制約のみのリレーションシップを使用すると、まだ子レコードがある親レコードを削除することはできず、親を介して子レコードにアクセスすることもできません。
データセット デザイナーでのデータのリレーションシップの手動作成
Visual Studio のデータ デザイン ツールを使用してデータ テーブルを作成するとき、データのソースから情報を収集できる場合は、リレーションシップが自動的に作成されます。 ツールボックスの [データセット] タブから手動でデータ テーブルを追加する場合は、リレーションシップの手動作成が必要になる場合があります。 プログラムによる DataRelation オブジェクトの作成については、「DataRelation の追加」を参照してください。
データ テーブル間のリレーションシップは、データセット デザイナーでは線として表示され、キーと無限大のグリフによってリレーションシップの一対多の側面が示されます。 既定では、リレーションシップの名前はデザイン サーフェイスに表示されません。
注意
この記事で紹介する Visual Studio ユーザー インターフェイス要素の一部は、お使いのコンピューターでは名前や場所が異なる場合があります。 Visual Studio のエディションや環境設定がお使いのものと異なる場合があります。 詳細については、「Visual Studio IDE のカスタマイズ」を参照してください。
2 つのデータ テーブル間にリレーションシップを作成するには
データセット デザイナーでご自分のデータセットを開きます。 詳細については、「チュートリアル: データセット デザイナーを使用したデータセットの作成」を参照してください。
[データセット] ツールボックスから Relation オブジェクトをリレーションシップの子データ テーブルにドラッグします。
[リレーションシップ] ダイアログ ボックスが開き、 [子テーブル] ボックスに Relation オブジェクトをドラッグしたテーブルが設定されます。
[親テーブル] ボックスから親テーブルを選択します。 親テーブルには、一対多リレーションシップの "一" 側のレコードが含まれます。
[子テーブル] ボックスに正しい子テーブルが表示されていることを確認します。 子テーブルには、一対多リレーションシップの "多" 側のレコードが含まれます。
[名前] ボックスにリレーションシップの名前を入力するか、選択したテーブルに基づく既定の名前をそのまま使用します。 これは、コード内の実際の DataRelation オブジェクトの名前です。
[キー列] と [外部キー列] の一覧で、テーブルを結合する列を選択します。
リレーションシップと制約のどちらか一方または両方を作成するかどうかを選択します。
[入れ子になった関係] ボックスをオンまたはオフにします。 このオプションを音にすると、Nested プロパティが
true
に設定され、それらの行が XML データとして書き込まれるとき、または XmlDataDocument と同期されるときに、リレーションシップの子の行が親の列に入れ子にされます。 詳しくは、「DataRelation の入れ子化」をご覧ください。これらのテーブルのレコードを変更するときに適用される規則を設定します。 詳細については、「Rule」を参照してください。
[OK] をクリックしてリレーションシップを作成します。 デザイナーで 2 つのテーブルの間にリレーションシップの線が表示されます。
データセット デザイナーでリレーションシップの名前を表示するには
データセット デザイナーでご自分のデータセットを開きます。 詳細については、「チュートリアル: データセット デザイナーを使用したデータセットの作成」を参照してください。
[データ] メニューの [リレーションシップ ラベルの表示] を選択して、リレーションシップ名を表示します。 リレーションシップ名を非表示にするには、そのコマンドをオフにします。