最後に、データセットを使ったレコードの削除について見ていこう。レコードの削除もこれまでのレコード追加や更新と同様に、まずデータテーブルからレコードを削除し、それをUpdateメソッドにより実際のテーブルに反映すればよい。
まず、データテーブルから削除対象となるDataRowオブジェクトを取得する。これは更新処理と同様で、例えばDataRowCollectionクラスのFindメソッドを使用する。
次に、削除しようとしているDataRowオブジェクトのDeleteメソッドを呼び出してレコードを削除する。これでレコードの削除は完了だ。
ただし、Deleteメソッドにより削除したレコードは、Findメソッドなどでは見つからなくなるが、本当にそのレコードが削除されるわけではない。もし削除してしまったら、データベース上のテーブルにあるレコードを削除するときの手がかりがまったくなくなってしまう。
実際には、Deleteメソッドは「このレコードは削除されました」というマークをDataRowオブジェクトに付ける。このマークの実体は、レコードの状態を示すRowStateプロパティである。Deleteメソッドを呼び出したときには、このプロパティにDataRowState.Deletedがセットされる。この値がセットされたレコードは、FindメソッドやDataTableクラスのSelectメソッドでは検索されない。
このプロパティはまた、追加や更新(書き換え)を行ったDataRowオブジェクトを示すのにも利用される。更新のためにDataRowオブジェクト内のカラムの値を書き換えたときには、RowStateプロパティにDataRowState.Modifiedがセットされる。また、新しく追加されたDataRowオブジェクトにはDataRowState.Addedがセットされている。なお、データセットにレコードを読み込んだ時点のRowStateプロパティの値は、DataRowState.Unchangedである。
ちなみに、データテーブルからDataRowオブジェクトを本当に削除する(取り除く)には、Rowsプロパティに対してRemoveあるいはRemoveAtメソッドを使用する。すでに述べたように、この場合にUpdateメソッドを呼び出してもデータベースの対応するレコードは削除されない。
■削除データのデータベースへの反映
Deleteメソッドによりレコードの削除が完了すれば、次はdelete文を設定したSqlCommandオブジェクトを作成し、データアダプタのDeleteCommandプロパティにセットしてからUpdateメソッドを呼び出す。
削除に対しても更新時と同様な同時実行制御が必要だ。例えば、取得したレコードを不要であると判断し削除しようとしても、すでにそのレコードをだれかが書き換えて、不要なレコードではなくなっている(=削除してはいけないレコードに変わっている)かもしれない。
ここではSqlCommandBuilderクラスを利用したサンプル・プログラムを以下に示しておく。なお本来であれば、ここまでのサンプル・プログラムと同様に、publishersテーブルに対して、指定されたpub_id値を持ったレコードを削除したいところだが、publishersテーブルのレコードのpub_idカラムの値は、ほかのテーブルのレコードから参照されているため、単独では削除できないような設定がなされている(この設定は「リレーションシップ」と呼ばれるもので、サンプル・データのインストール時に設定される)。よって次のサンプル・プログラムでは、pubsデータベースに含まれている「employee」テーブルの1つのレコードを削除している。
// cbdeleteds.cs
using System;
using System.Data;
using System.Data.SqlClient;
public class BuilderDeleteFromDataSet {
public static void Main() {
string connStr = "Server=(local)\\NetSDK;"
+ "Trusted_Connection=yes;"
+ "database=pubs";
string selectStr = "SELECT * FROM employee";
// 接続用オブジェクトの作成
SqlConnection conn = new SqlConnection();
conn.ConnectionString = connStr;
// select用コマンド・オブジェクトの作成
SqlCommand selectCmd = new SqlCommand();
selectCmd.Connection = conn;
selectCmd.CommandText = selectStr;
// データアダプタの作成
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = selectCmd;
// データセットへの読み込み
DataSet ds = new DataSet();
da.Fill(ds, "employee");
DataTable dt = ds.Tables["employee"];
// 主キーの設定
dt.PrimaryKey = new DataColumn[] { dt.Columns["emp_id"] };
// データの削除
DataRow targetRow;
targetRow = dt.Rows.Find("PDI47470M");
targetRow.Delete();
// コマンド自動作成
SqlCommandBuilder cb = new SqlCommandBuilder(da);
// データベースの更新
da.Update(ds, "employee");
}
}
// コンパイル方法:csc cbdeleteds.cs
このプログラムでは、データセットにレコードを読み込むためのselect文で「select * ……」をセットしているため、データテーブルにはすべてのカラムのデータが作成される。この場合には、すべてのカラムの値が元のままかどうかをチェックする長いwhere句を含んだdelete文が自動生成される。
自動生成されたupdate文やdelete文を解説するために、ほんの少し内容が難しくなってしまったが、「基礎講座」ということで今回はこのあたりで終わりとさせていただく。取りあえず今回までで、ADO.NETを利用した基本的なデータベース・アクセスについては解説できた。次回は少し趣向を変え、Visual Studio .NETのIDEを使ったADO.NETプログラミングについて解説する予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.