外部キー制約や自動インクリメント列を使いこなして、追加・更新・削除されたマスタ/詳細データをDBに反映する。
powered by Insider.NET
前回ではマスタ/詳細テーブルを参照する画面を作成し、さらにID番号をそのまま表示しているテキストボックスやDataGridViewコントロールの列を、顧客名や商品名で表示/設定できるコンボボックスに変更しました。
今回は、前回作成したサンプル・プログラム*1に機能を追加し、追加・更新・削除を行った注文データや注文明細データがデータベースに保存されるようにしていきます。この処理では2つのテーブルを同時に扱わなければならず、その整合性を保つために、処理するテーブルやデータテーブルの順番をよく考慮する必要があります。
*1 前回作成したサンプル・プログラムのプロジェクトは、前回の最後のページからダウンロードできます。
ではプログラミングの前準備として、まずはリレーションシップの設定から行っていきましょう。
最初に、データセットに追加されている注文データテーブルと注文明細データテーブルの間のリレーションシップ(前回で「注文/注文明細リレーション」という名前を付けました)に対して「外部キー制約」を設定しておきます。
外部キー制約とは、親子関係にある2つのテーブルにおいて、子テーブルの外部キーの値を主キーとする親テーブルのレコードが存在しなければならないという制約です。この制約に反するようなレコードの操作はエラーとなるため、制約を設定しておくことで親子テーブル間での整合性を常に保つことができます。以上はデータベースでの話ですが、データセットにおけるリレーションシップ(=DataRelationオブジェクト)においても、まったく同様に設定できるようになっています。
実際、本稿で題材にしているNorthwindデータベースでは、注文テーブルと注文明細テーブルの間のリレーションシップには外部キー制約が設定されていますので、同じ設定をデータセットにも行っておきましょう*2。
*2 データセットにデータテーブルを追加した時点でリレーションシップ自体は自動的に作成されますが、データベースで設定されている外部キー制約などの設定については反映されないようです。
ここでは「注文/注文明細リレーション」をダブルクリックして[リレーションシップ]ダイアログを開き、以下の画面のように「外部キー制約」を変更します。
(1)のリレーションシップをダブルクリック
[作成する制約の選択][UpdateRuleの設定][ルールの削除]を設定
(2)で外部キー制約を有効にすると、注文データが存在しないのに注文明細データは存在するといったデータテーブルの状態はエラーとして検出されるようになります(例外が発生します)。この状態は例えば、注文明細データを残したまま、その親となる注文データを削除した場合などに起こります。プログラムでは外部キー制約に違反しないようにレコードを操作していく必要があります。
上記の画面では、併せてほかの2つの設定も行っています。(3)では[UpdateRuleの設定]を「Cascade」に設定しておきます。これは「連鎖更新」を有効にするためのものです。この設定により、注文データテーブルの主キー(OrderID番号)が変更されたときに、注文明細データテーブルの方の外部キー(OrderID番号)も自動的に同じ値に更新されるようになります。これがなぜ必要になるかについては後述します。
最後に、(3)の[ルールの削除]*3を「Cascade」に変更します。これにより「連鎖削除」が行われます。つまり注文データテーブルのレコードを削除すれば、それに関連している注文明細データテーブルのレコードも自動的に削除されるようになります。
*3 この「ルールの削除」という表示は日本語訳が間違っています。なぜか英語版のVisual Studio 2005の「Delete Rule」を直訳してしまっています(「Relationship Dialog Box」参照)。すぐ上の「UpdateRuleの設定」とそろえるならば、「DeleteRuleの設定」とすべきものです。
以上で外部キー制約の設定は完了です。ではここで、ちょっとプログラムを実行してみましょう。
Copyright© Digital Advantage Corp. All Rights Reserved.