- PR -

DataTable.AcceptChanges()の戻り値がnull

投稿者投稿内容
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2006-05-16 21:55
おそらく大きく勘違いしていると思うのですが
DataTable.GetChanges()の戻り値がnullになってしまいます。
以下がコードです。

DbDataAdapter da = new SqlDataAdapter(sqlStr, connStr);

DataSet ds = new DataSet();
da.Fill(ds, "work");
DataTable table = ds.Tables[0]; // この時点で2レコードあります。
table.AcceptChanges();

table.Merge(table2); // table2をマージして3レコードになります。
table = table.GetChanges(); // ここで、AcceptChanges()後の違いが取得したいがnullが返る。

あるいは、AcceptChanges()後に
ブレークポイントをかけて、データベースを更新し、
GetChanges()を呼んでもやっぱりnull。

そもそも使い方、考え方が違うのでしょうか?

環境はVisualStudio2005です。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-05-16 22:14
GetChanges の解説はこうなってますよ。
引用:

前回 DataTable を読み取るか、AcceptChanges を呼び出した以降にこのデータセットに対して行われたすべての変更が格納されているこのデータセットのコピーを取得します。



ついでに AcceptChanges の解説も。
引用:

AcceptChanges が呼び出されると、編集モードの DataRow オブジェクトは、正常に編集を終了します。また、DataRowState も変更されます。すべての Added 行および Modified 行は、Unchanged に変更されます。Deleted 行は削除されます。

頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2006-05-16 23:57
すいません。いろいろ試していたので、最終的に変なことになってますね。
table.Merge(table2);じゃ、
これって、DataTableのインスタンスが変更されただけかな?

table.Merge(table2)の代わりに
SqlDataReaderとSqlCommandを使って、update文を実行っていうのを
はさんでも結果は同じでした。

解説どおりだと、これでもGetChanges()の結果が取れそうなものかな?
と思うのですが。
(大きく勘違いしている予感です)
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2006-05-17 10:10
AcceptChanges()の後に以下で更新したら、GetChanges()の戻り値ちゃんと
返ってきました。
table.PrimaryKey = new DataColumn[] { table.Columns["xxx"] };
DataRow targetRow;
targetRow = table.Rows.Find("yyy");
targetRow["ZZZ"] = "zzz";
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2006-05-17 11:56
こんにちは。

とりあえずテスト用コードを作って調べてみました。

コード:

      DataTable dt = new DataTable();
      dt.Columns.Add("name", typeof(string));
      dt.Columns.Add("position", typeof(string));
      dt.Rows.Add("R・田中一郎", "コウガブラック");
      dt.Rows.Add("大戸島さんご", "コウガブルー");
      dt.Rows.Add("曲垣剛", "コウガレッド");
      dt.Rows.Add("兵頭真", "コウガイエロー");
      dt.Rows.Add("西園寺えりか", "コウガピンク");
      dt.Rows.Add("鳥坂センパイ", "鳥頭司令");
      dt.AcceptChanges();

      DataTable dt2 = new DataTable();
      dt2.Columns.Add("name", typeof(string));
      dt2.Columns.Add("position", typeof(string));
      dt2.Rows.Add("成原博士", "大帝王ナリハラ");
      dt2.Rows.Add("西園寺まりい", "ヘル・マリィ");
      dt2.Rows.Add("鰯水等", "イワッシ将軍");
      dt2.AcceptChanges();

      dt.Merge(dt2);


この結果を見る限りでは、Mergeしたあとは dt の RowState は全て Unchanged
になっています。ということは GetChanges() で null が返ってくるのは正しい処理なの
ではないでしょうか。
頭脳パンさんのやりたいことは(文章から察するに) dt に追加された dt2 の3行分が
Added で返ってくるのでは?ということだと思うのですが、これは上記のようなコードを書
いて試せばすぐわかりそうな気がしますよ。

# テストデータについてのクレームは受け付けません
頭脳パン
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 89
投稿日時: 2006-05-17 12:40
検証コードありがとうございます。

むしろ、そういうデータの挿入ってできるんですね。
SQLからだけだと思ってました。

Addでは、Unchangedということは修正とはみなされないってことですかね。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-05-17 12:51
引用:

Addでは、Unchangedということは修正とはみなされないってことですかね。


違います。
Add した行の RowState は Added です。
その後、AcceptChanges を呼び出すことで RowState が Unchanged に変化します。
AcceptChanges する前に GetChanges を呼び出せば Add した行が返ってきます。

ついでに、Fill を呼び出してテーブルに作られた行も、本来は Added になります。しかし、DataAdapter.AcceptChangesDuringFill プロパティがデフォルトで true の為、内部で自動的に AcceptChanges が呼び出されて各行の RowState が Unchanged になります。

Merge は RowState が変化するわけではないんですよね(行の情報は変わっていないので。所属するテーブルの変更というのも行の情報が変化と考えることもできるんですが)。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-05-17 13:12
この手の話題はあまり詳しくないので、登場したくなかったんですが、何かに導か
れるように「返信」ボタンをクリックしてしまいましたw

引用:

頭脳パンさんの書き込み (2006-05-17 12:40) より:

Addでは、Unchangedということは修正とはみなされないってことですかね。



DataSet の立場になって考えて見ると理解しやすいと思いますよ。

アダプターからセットされたデータの塊に対して行われた何らかの処理を、効率よく、
且つ他のタスクや他のユーザーとの変更の優先順序などからおかしな状態にならない
よう更新するためには、対象のレコードが「変更」された場合と「追加」された場合
では明らかに行う処理が異なります。
なので、ステータスが同じじゃまずい訳です。

#最近 DataSet は勉強したばっかり(^▽^;)


[ メッセージ編集済み 編集者: R・田中一郎 編集日時 2006-05-17 13:17 ]

スキルアップ/キャリアアップ(JOB@IT)