2007/08/13 11:38
前回、フォーム画面を変更したので、今回はそのコードを修正していきます。
まず、ベンダー毎の商品単価テーブルのデータアダプタを用意します。
クラスのprivate変数として
// dat_item_priceのデータアダプタ
private NpgsqlDataAdapter m_da_dat_item_price = new NpgsqlDataAdapter();
// mst_vendorのデータアダプタ
private NpgsqlDataAdapter m_da_mst_vendor = new NpgsqlDataAdapter();
フォームのロードイベントで、そのデータアダプタを構築します。
// dat_item_priceのテーブルアダプタ構築
// selectコマンド
m_da_dat_item_price.SelectCommand = new NpgsqlCommand
(
"select"
+ " item_id"
+ ", vendor_id"
+ ", price"
+ ", create_date"
+ ", update_date"
+ " from"
+ " dat_item_price"
+ " order by item_id, vendor_id",
m_conn
);
// insertコマンド
m_da_dat_item_price.InsertCommand = new NpgsqlCommand
(
"insert into dat_item_price ("
+ " item_id"
+ ", vendor_id"
+ ", price"
+ " ) values ("
+ " :item_id"
+ ", :vendor_id"
+ ", :price"
+ " )",
m_conn
);
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("price" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
// updateコマンド
m_da_dat_item_price.UpdateCommand = new NpgsqlCommand
(
"update dat_item_price set"
+ " vendor_id=:vendor_id"
+ ", price=:price"
+ ", update_date=current_timestamp"
+ " where"
+ " item_id=:item_id"
+ " and vendor_id=:org_vendor_id",
m_conn
);
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("price" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("org_vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// deleteコマンド
m_da_dat_item_price.DeleteCommand = new NpgsqlCommand
(
"delete from dat_item_price"
+ " where"
+ " item_id=:item_id"
+ " and vendor_id=:vendor_id",
m_conn
);
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// RowUpdatedイベントの追加
m_da_dat_item_price.RowUpdated += new NpgsqlRowUpdatedEventHandler(dat_item_priceRowUpdated);
// mst_vendorのデータアダプタ(グリッドのコンボボックス用)
// selectコマンド
m_da_mst_vendor.SelectCommand = new NpgsqlCommand
(
"select"
+ " vendor_id"
+ ", vendor_name"
+ ", create_date"
+ ", update_date"
+ " from"
+ " mst_vendor"
+ " order by vendor_id",
m_conn
);
RowUpdateイベント関数を追加します。
// dat_item_priceのデータアダプタのRowUpdatedイベント
private void dat_item_priceRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
{
if (e.Status == UpdateStatus.Continue)
{
if (e.StatementType == StatementType.Insert)
{
// create_date,update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select create_date, update_date from dat_item_price where item_id="+e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["create_date"] = reader["create_date"];
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
else if (e.StatementType == StatementType.Update)
{
// update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select update_date from dat_item_price where item_id=" + e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
}
}
データセットにdat_item_priceとmst_vendorを加えます。
m_da_dat_item_price.Fill(m_ds, "dat_item_price");
m_da_mst_vendor.Fill(m_ds, "mst_vendor");
ここで、今回の本題となるリレーションを定義します。
今回の画面では、上に商品マスタ、下にベンダー毎の単価のグリッドが配置されています。
上の商品マスタを1行選択したとき、下の単価データは、選択された商品の内容が表示されなければなりません。
データセット内で、mst_itemとdat_item_priceの関係をリレーションで定義してやることで、これを簡単に実現することができます。
まず、データセットのmst_itemとdat_item_priceの関連を定義します。
// リレーション作成
m_ds.Relations.Add(new DataRelation("rel_dat_item_price",
m_ds.Tables["mst_item"].Columns["item_id"],
m_ds.Tables["dat_item_price"].Columns["item_id"]));
rel_dat_item_priceという名前でリレーションを定義しています。
次に、グリッドやナビゲータのデータソースとなっているbind_dat_item_priceを設定します。
// bind_dat_item_priceを設定
bind_dat_item_price.DataSource = bind_mst_item;
bind_dat_item_price.DataMember = "rel_dat_item_price";
ここで注意するのは、DataSourceにはmst_itemのためのBindingSourceのbind_mst_itemを、DataMemberにはリレーションrel_dat_item_priceを設定することです。
これにより、mst_itemとdat_item_priceが関連付けされ、またグリッドも連動するようになります。
次に、grid_dat_item_priceの各列を関連付けます。
// dat_item_price
col_dat_item_id.DataPropertyName = "item_id";
col_dat_vendor_id.DataPropertyName = "vendor_id";
col_dat_vendor_id.DataSource = m_ds.Tables["mst_vendor"];
col_dat_vendor_id.DisplayMember = "vendor_name";
col_dat_vendor_id.ValueMember = "vendor_id";
col_dat_price.DataPropertyName = "price";
col_dat_create_date.DataPropertyName = "create_date";
col_dat_update_date.DataPropertyName = "update_date";
これで動作させると、次のような問題が発生します。

データを2行追加しようとすると

というエラーが発生。また、

というように、mst_itemとdat_item_priceが連動しません。
これは、item_idがnullとなっているため、こういった現象になります。
これまでは、1つのテーブルに対するアクセスだったため、RowUpdatedイベントでitem_idを取ってきて、データセットに入れてあげればよかったのですが、リレーションする列は何らかの一意なIDを持っておく必要があります。
これには、テーブルアダプタのm_ds.Tables["mst_item"]の、item_id列をAutoIncrementにして、自動的にIDがセットされるようにします。
今回、mst_itemのitem_idはserialにしているため、currval('mst_item_item_id_seq')でmst_item_item_id_seqの次の値を取ってきて入れてやれば一番いいんですが、シリアル値は値の増加があった同一トランザクション内でないと取得できません。
なので、mst_itemのitem_idの最大値+1をセットするのが一番しっくりくる気がします(ウィザードで生成されるコードではそうなっているようです)。
ただ、そのためにはitem_idの最大値+1を取得するSQLを発行しないといけないので、ちょっと面倒。
そこで、IDに負の数はないという前提で、AutoIncrementの初期値を-1、増加量も-1にしてしまうというやり方があります。
データ保存するまでは、item_idにマイナスの値が入りますが、各行はユニークなIDを持ちます。そして保存時のRowUpdatedイベントによって、保存された実際のIDがデータセットにセットされなおします。
// mst_itemのitem_idをAutoIncrementにする
DataColumn dc_item_id = m_ds.Tables["mst_item"].Columns["item_id"];
dc_item_id.AutoIncrement = true;
dc_item_id.AutoIncrementSeed = -1;
dc_item_id.AutoIncrementStep = -1;
これで、保存ボタンが押されたとき
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"]);
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"]);
として、データベースに書き込みたいところですが、これだと、insertのときはいいのですが、deleteのときは、リレーションしているデータがあるためmst_itemのレコードは削除できません。
では、
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"]);
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"]);
として、dat_item_priceを先に更新しようとすると、今度はinsertでエラーが出ます。
こういう場合、delete,update,insertされたレコードを別々に処理することでうまく保存することができます。
// delete
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted));
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted));
// update
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent));
// insert
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added));
リレーションで自分自身を指すような構造のときは、さらに工夫が必要になりそうな気がします。。。
最終的にソースは次のようになります。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;
namespace Npgsql_sample
{
public partial class form_mst_item : Form
{
// メンバ変数
// データベース接続子
private NpgsqlConnection m_conn = new NpgsqlConnection
(
"Server=localhost;"
+ "Port=5432;"
+ "User Id=Npgsql_sample;"
+ "Password=hogehoge;"
+ "Database=Npgsql_sample;"
+ "Encoding=UNICODE"
);
// mst_itemのデータアダプタ
private NpgsqlDataAdapter m_da_mst_item = new NpgsqlDataAdapter();
// mst_categoryのデータアダプタ
private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
// dat_item_priceのデータアダプタ
private NpgsqlDataAdapter m_da_dat_item_price = new NpgsqlDataAdapter();
// mst_vendorのデータアダプタ
private NpgsqlDataAdapter m_da_mst_vendor = new NpgsqlDataAdapter();
// データセット
private DataSet m_ds = new DataSet();
public form_mst_item()
{
InitializeComponent();
}
private void form_mst_item_Load(object sender, EventArgs e)
{
// mst_itemのデータアダプタ構築
// selectコマンド
m_da_mst_item.SelectCommand = new NpgsqlCommand
(
"select"
+ " item_id"
+ ", item_name"
+ ", category_id"
+ ", create_date"
+ ", update_date"
+ " from"
+ " mst_item"
+ " order by item_name",
m_conn
);
// insertコマンド
m_da_mst_item.InsertCommand = new NpgsqlCommand
(
"insert into mst_item ("
+ " item_name"
+ ", category_id"
+ " ) values ("
+ " :item_name"
+ ", :category_id"
+ " )",
m_conn
);
m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("item_name" , NpgsqlTypes.NpgsqlDbType.Text , 0, "item_name" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
// updateコマンド
m_da_mst_item.UpdateCommand = new NpgsqlCommand
(
"update mst_item set"
+ " item_name=:item_name"
+ ", category_id=:category_id"
+ ", update_date=current_timestamp"
+ " where"
+ " item_id=:item_id",
m_conn
);
m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_name" , NpgsqlTypes.NpgsqlDbType.Text , 0, "item_name" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// deleteコマンド
m_da_mst_item.DeleteCommand = new NpgsqlCommand
(
"delete from mst_item"
+ " where"
+ " item_id=:item_id",
m_conn
);
m_da_mst_item.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// RowUpdatedイベントの追加
m_da_mst_item.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_itemRowUpdated);
// mst_categoryのデータアダプタ構築(グリッドのコンボボックス用)
m_da_mst_category.SelectCommand = new NpgsqlCommand
(
"select"
+ " category_id"
+ ", category_name"
+ ", create_date"
+ ", update_date"
+ " from"
+ " mst_category"
+ " order by category_name",
m_conn
);
// dat_item_priceのデータアダプタ構築
// selectコマンド
m_da_dat_item_price.SelectCommand = new NpgsqlCommand
(
"select"
+ " item_id"
+ ", vendor_id"
+ ", price"
+ ", create_date"
+ ", update_date"
+ " from"
+ " dat_item_price"
+ " order by item_id, vendor_id",
m_conn
);
// insertコマンド
m_da_dat_item_price.InsertCommand = new NpgsqlCommand
(
"insert into dat_item_price ("
+ " item_id"
+ ", vendor_id"
+ ", price"
+ " ) values ("
+ " :item_id"
+ ", :vendor_id"
+ ", :price"
+ " )",
m_conn
);
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("price" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
// updateコマンド
m_da_dat_item_price.UpdateCommand = new NpgsqlCommand
(
"update dat_item_price set"
+ " vendor_id=:vendor_id"
+ ", price=:price"
+ ", update_date=current_timestamp"
+ " where"
+ " item_id=:item_id"
+ " and vendor_id=:org_vendor_id",
m_conn
);
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("price" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("org_vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// deleteコマンド
m_da_dat_item_price.DeleteCommand = new NpgsqlCommand
(
"delete from dat_item_price"
+ " where"
+ " item_id=:item_id"
+ " and vendor_id=:vendor_id",
m_conn
);
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id" , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id" , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// RowUpdatedイベントの追加
m_da_dat_item_price.RowUpdated += new NpgsqlRowUpdatedEventHandler(dat_item_priceRowUpdated);
// mst_vendorのデータアダプタ(グリッドのコンボボックス用)
// selectコマンド
m_da_mst_vendor.SelectCommand = new NpgsqlCommand
(
"select"
+ " vendor_id"
+ ", vendor_name"
+ ", create_date"
+ ", update_date"
+ " from"
+ " mst_vendor"
+ " order by vendor_id",
m_conn
);
// データセット生成
m_da_mst_item.Fill(m_ds, "mst_item");
m_da_mst_category.Fill(m_ds, "mst_category");
m_da_dat_item_price.Fill(m_ds, "dat_item_price");
m_da_mst_vendor.Fill(m_ds, "mst_vendor");
// mst_itemのitem_idをAutoIncrementにする
DataColumn dc_item_id = m_ds.Tables["mst_item"].Columns["item_id"];
dc_item_id.AutoIncrement = true;
dc_item_id.AutoIncrementSeed = -1;
dc_item_id.AutoIncrementStep = -1;
// リレーション作成
m_ds.Relations.Add(new DataRelation("rel_dat_item_price",
m_ds.Tables["mst_item"].Columns["item_id"],
m_ds.Tables["dat_item_price"].Columns["item_id"]));
// bind_mst_itemを設定
bind_mst_item.DataSource = m_ds;
bind_mst_item.DataMember = "mst_item";
// bind_dat_item_priceを設定
bind_dat_item_price.DataSource = bind_mst_item;
bind_dat_item_price.DataMember = "rel_dat_item_price";
// カラムの関連付け
/// mst_item
col_item_id.DataPropertyName = "item_id";
col_item_name.DataPropertyName = "item_name";
col_category_id.DataPropertyName = "category_id";
col_category_id.DataSource = m_ds.Tables["mst_category"];
col_category_id.DisplayMember = "category_name";
col_category_id.ValueMember = "category_id";
col_create_date.DataPropertyName = "create_date";
col_update_date.DataPropertyName = "update_date";
// dat_item_price
col_dat_item_id.DataPropertyName = "item_id";
col_dat_vendor_id.DataPropertyName = "vendor_id";
col_dat_vendor_id.DataSource = m_ds.Tables["mst_vendor"];
col_dat_vendor_id.DisplayMember = "vendor_name";
col_dat_vendor_id.ValueMember = "vendor_id";
col_dat_price.DataPropertyName = "price";
col_dat_create_date.DataPropertyName = "create_date";
col_dat_update_date.DataPropertyName = "update_date";
}
// 保存ボタンのクリック
private void cmd_save_Click(object sender, EventArgs e)
{
int update_count = 0;
try
{
// delete
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted));
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted));
// update
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent));
// insert
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added));
}
catch (Exception ex)
{
MessageBox.Show("商品の保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// mst_itemのデータアダプタのRowUpdatedイベント
private void mst_itemRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
{
if (e.Status == UpdateStatus.Continue)
{
if (e.StatementType == StatementType.Insert)
{
// item_idとcreate_date,update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select item_id, create_date, update_date from mst_item where item_id=currval('mst_item_item_id_seq')", m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["item_id"] = reader["item_id"];
e.Row["create_date"] = reader["create_date"];
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
else if (e.StatementType == StatementType.Update)
{
// update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_item where item_id="+e.Row["item_id"].ToString(), m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
}
}
// dat_item_priceのデータアダプタのRowUpdatedイベント
private void dat_item_priceRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
{
if (e.Status == UpdateStatus.Continue)
{
if (e.StatementType == StatementType.Insert)
{
// create_date,update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select create_date, update_date from dat_item_price where item_id="+e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["create_date"] = reader["create_date"];
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
else if (e.StatementType == StatementType.Update)
{
// update_dateを取得
NpgsqlCommand cmd = new NpgsqlCommand("select update_date from dat_item_price where item_id=" + e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
try
{
NpgsqlDataReader reader = cmd.ExecuteReader();
reader.Read();
e.Row["update_date"] = reader["update_date"];
}
catch (Exception)
{
throw;
}
}
}
}
private void form_mst_item_FormClosing(object sender, FormClosingEventArgs e)
{
int update_count = 0;
update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added).Length;
update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted).Length;
update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added).Length;
update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted).Length;
if (update_count > 0) // 1件以上更新されていれば確認画面を表示
{
if (MessageBox.Show("商品が保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
e.Cancel = true;
}
}
}
}
}