by WebSurfer
2010年9月4日 20:01
Visual Studio のウィサードを使うと、SQL Server や Access のテーブルを表示して、レコードを INSERT, DELETE, UPDATE するプログラムが簡単に作れます。
ただし、Access でオートナンバー(SQL Server で言うと IDENTITY)を使っている場合、INSERT した時に DB 側で設定したオートナンバー値を DataSet に書き込むところまでは面倒を見てくれません。(SQL Server の場合は面倒見てくれます)
これは、JET データベースエンジン(Microsoft Access およびその他の小規模アプリケーションで使用されている)では、単一バッチで複数のステートメントを実行できないということが理由のようです。
詳しくは、MSDN ライブラリの @@IDENTITY クライシスを管理する の「Microsoft Access/JET の問題」のセクションを参照してください。
ここでは、DataAdapter の RowUpdated イベントを使用して自動生成されたコードとは別のクエリを実行し、オートナンバー値を DataSet に書き込む具体的な例を紹介します。
まず、いつもの手順で型付 DataSet を作り、データソースウィンドウからテーブルを Form にドラッグ&ドロップしてアプリケーションを作ります。以下の画像がその例です。ここまではコードは一行も書く必要がありません。
ただし、ここまでの実装では、新しいレコードを INSERT したとき、オートナンバーとなっている ID の値が DataSet に書き戻されていないので、DataGridView に表示されている ID 値は正しくありません。
そこで、INSERT 直後に発生する DataAdapter の RowUpdated イベントのハンドラで、"SELECT @@IDENTITY" クエリを使って新規 ID 値を取得し、それを DataSet に書き込んでやります。
具体的には、TableAdapter を partial class を使って拡張します。ソリューションにクラスファイルを追加して、以下のようなコードを実装します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;
namespace AccessWithAutoNumberAndDataSet.DataSet1TableAdapters
{
public partial class XXXTableAdapter
{
public void SetHandler()
{
this.Adapter.RowUpdated +=
new OleDbRowUpdatedEventHandler(Adapter_RowUpdated);
}
private OleDbCommand cmd =
new OleDbCommand("SELECT @@IDENTITY", null);
private void Adapter_RowUpdated(Object sender, OleDbRowUpdatedEventArgs e)
{
cmd.Connection = e.Command.Connection;
cmd.Transaction = e.Command.Transaction;
if (e.StatementType == StatementType.Insert &&
e.Status == UpdateStatus.Continue)
{
object obj = cmd.ExecuteScalar();
if (obj != null && obj.GetType() != typeof(DBNull))
{
e.Row["ID"] = (int)obj;
e.Row.AcceptChanges();
}
}
}
}
}
これだけでは、ハンドラがイベントにアタッチされていないので、自動生成された Form のコードのコンストラクタに、上記 partial class で定義した SetHandler メソッドを追記します。以下のような感じです。
namespace AccessWithAutoNumberAndDataSet
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// これを追加。
this.xXXTableAdapter.SetHandler();
}
これで、新規 ID 値が DataSet に書き込まれ、DataGridView に表示されるようになります。