none
CデータセットのMerge、ImportRowについて教えてください。 RRS feed

  • 質問

  • C#のデータセットのMerge、ImportRowについて教えてください。

    現在FormAとFormBがあり、FormAが一覧表示、FormBが新規レコードの入力画面に
    なっています。

    新規レコードを追加する際はFormAからFormBを開いて入力します。

    その際FormB内ではDataTableのNewRow、AddRowでDataTableにレコードが追加され
    FormBが閉じられた際、FormB側のDataTableのデータをFormA側のDataTableに
    追加したいのですが、1回目はいいのですが、2回目のデータ追加時に問題が起きます。

    DataTable.Mergeを使った場合は行数が増えず、DataTable.ImportRowを使った場合は
    キー列の値が重複している旨のエラーがでます。

    どうもDataTableのNewRow、AddRowでレコードを追加した場合、主キー列が-1、-2・・・と
    自動連番されるようなのですが、FormBでレコードを追加するたびに-1、-2・・・と
    IDが付けられて、FormAでのMerge、ImportRowの処理の時点で主キー列の重複といった
    問題が出るようです。

    主キーが重複する場合は主キーを変更する処理も試してみましたが、型付DataTableのせいか
    読み取り専用となっていて変更ができないようになっています。

    FormA側のDataTableの参照をFormBに渡してしまい、FormB内でNewRow、AddRowすれば
    できるのは分かっているのですが、できるなら各フォーム内のDataTableにて
    処理を行い、最後に2つのDataTableをマージということができればと思って、
    その方向で取り組んでいるのですが、何か方法があるものなのででしょうか?

    2012年3月12日 18:40

回答

  • MergeやImportRowを使う以上、FormBのデータテーブルで採番された主キーが、FormAのデータテーブルの主キーに無いものでなければ追加することはできません。
    FromBは新規レコードの入力画面ということですので、新規レコードの追加しかないようですから、Mergeを使う必要は無いように思います。単純にFormBのデータテーブルを1行ずつ読みながら、FormAのデータテーブルに追加されてはいかがでしょうか?

    >FormA側のDataTableの参照をFormBに渡してしまい、FormB内でNewRow、AddRowすれば
    >できるのは分かっているのですが

    この理由は何でしょうか? その理由によってはもっと良い方法があるかもしれません。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    2012年3月13日 0:55
    モデレータ
  • 複数のフォーム間であまりDataTableを持ちまわりたくないという気持ちがあり、効率が悪くともフォームごとにDataTableをもたせ、
    各フォーム内で処理を完結させて、最後にマージなり差分を削除するなりして、結果を元のフォームのDataTableに反映ということがしたかったのです。。

    「複数のフォーム間であまりDataTableを持ちまわりたくない」という感覚は少し違います。複数フォーム間で同じDataTableを持ち歩くわけではありません。sumomopurinさんは「参照」という言葉を使われているのでご存じだとは思いますが、参照というのはあくまでのその在り処を示しているだけのものです。また、sumomopurinさんは「FormA側のDataTable」という表現をされていますが、そのDataTableはFormAにあるわけではありません。FormAはヒープ上にあるDataTableの在り処を知っているというだけのことです。FormAは自分でそのDataTableを作ったのですから、その在り処を知っているのは当然のことです。
    ですから、FormAからFormBを開く際に、FormAは「その在り処」をFormBへ教えてあげればよいだけのことです。特別な理由でもない限り、FormBに「その在り処」を内緒にするのは意地悪だと思いませんか?(笑)


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    2012年3月13日 4:10
    モデレータ

すべての返信

  • MergeやImportRowを使う以上、FormBのデータテーブルで採番された主キーが、FormAのデータテーブルの主キーに無いものでなければ追加することはできません。
    FromBは新規レコードの入力画面ということですので、新規レコードの追加しかないようですから、Mergeを使う必要は無いように思います。単純にFormBのデータテーブルを1行ずつ読みながら、FormAのデータテーブルに追加されてはいかがでしょうか?

    >FormA側のDataTableの参照をFormBに渡してしまい、FormB内でNewRow、AddRowすれば
    >できるのは分かっているのですが

    この理由は何でしょうか? その理由によってはもっと良い方法があるかもしれません。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    2012年3月13日 0:55
    モデレータ
  • ありがとうございます。

    >MergeやImportRowを使う以上、FormBのデータテーブルで採番された主キーが、
    >FormAのデータテーブルの主キーに無いものでなければ追加することはできません。
    >FromBは新規レコードの入力画面ということですので、新規レコードの追加しかないようですから、
    >Mergeを使う必要は無いように思います。単純にFormBのデータテーブルを1行ずつ読みながら、
    >FormAのデータテーブルに追加されてはいかがでしょうか?

    何かスムースにDataTable同士をMergeなどできる方法があるかと悩みましたが、どうも無理っぽいですね。

    複数のフォーム間であまりDataTableを持ちまわりたくないという気持ちがあり、効率が悪くともフォームごとにDataTableをもたせ、
    各フォーム内で処理を完結させて、最後にマージなり差分を削除するなりして、結果を元のフォームのDataTableに反映ということがしたかったのです。。

    取り組んでみたのですがMerge()やImportRow()が上手くいかず、今回はお教えいただいたように1行ずつ地道に処理を行っていきたいと思います。

    どうもありがとうございました。

    2012年3月13日 3:00
  • 複数のフォーム間であまりDataTableを持ちまわりたくないという気持ちがあり、効率が悪くともフォームごとにDataTableをもたせ、
    各フォーム内で処理を完結させて、最後にマージなり差分を削除するなりして、結果を元のフォームのDataTableに反映ということがしたかったのです。。

    「複数のフォーム間であまりDataTableを持ちまわりたくない」という感覚は少し違います。複数フォーム間で同じDataTableを持ち歩くわけではありません。sumomopurinさんは「参照」という言葉を使われているのでご存じだとは思いますが、参照というのはあくまでのその在り処を示しているだけのものです。また、sumomopurinさんは「FormA側のDataTable」という表現をされていますが、そのDataTableはFormAにあるわけではありません。FormAはヒープ上にあるDataTableの在り処を知っているというだけのことです。FormAは自分でそのDataTableを作ったのですから、その在り処を知っているのは当然のことです。
    ですから、FormAからFormBを開く際に、FormAは「その在り処」をFormBへ教えてあげればよいだけのことです。特別な理由でもない限り、FormBに「その在り処」を内緒にするのは意地悪だと思いませんか?(笑)


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    2012年3月13日 4:10
    モデレータ
  • ありがとうございます。

    パスワードを失念してしまい返事が遅れましてすいませんでした。

    trapemiya様の返信についてよく考えてみて、また小さなテストコードも
    書いてみて今回参照を渡す方法の方がよいことがわかりました。
    これからさっそく作り直したいと思います。

    どうもありがとうございました!

    2012年3月15日 22:03