none
DataGridViewに3つ以上のテーブルを参照し、更新、追加を行う RRS feed

  • 質問

  • visual studio 2005 で C# Windowsアプリケーションの開発を行っています。

    C#は未経験です。

    DataGridViewに複数テーブルの参照した場合、Updateメソッドが使えないため、

    更新と登録部分で足踏みしています。

    sql文を発行して、DataGridViewに表示、更新、追加まで行いたいのですが、

    どうすればよいでしょうか?


    また、現在テーブルA,B,Cとあるとき、テーブルA(Id,a_nama,b_id(テーブルBの外部キー),c_id(テーブルCの外部キー))は

    テーブルB(ID,b_name)とテーブルC(ID,c_name)の外部キーを持っていて、

    DataGridViewにはテーブルAのデータソースをバインドしています。テーブルAの内容に加えて、

    テーブルBのname,テーブルCのnameをcombo boxで表示したとき、Data errorが発生しました。

    Bのnameはきちんと表示されましたが、Cのnameはまったく表示されない状態です。

    質問が2つになっていますが、どなたかアドバイスをよろしくお願いします。

     

     

    2012年1月11日 10:24

回答

  • DataGridViewに複数テーブルの参照した場合、Updateメソッドが使えないため、

    更新と登録部分で足踏みしています。

    更新対象となるのはテーブルAだけでしょうか? また、TableAdapterを使用されているのでしょうか? であれば、joinを使わずにSQL文を書いて下さい。
    例えば、

    select a.ID, a_name,
        (select b.b_name from テーブルB b where b.ID = a.ID) b_name,
        (select c.c_name from テーブルC c where c.ID = a.ID) c_name
    from テーブルA
    
    のように書くと、Updateメソッドが使用できるようになります。

    DataGridViewにはテーブルAのデータソースをバインドしています。テーブルAの内容に加えて、

    テーブルBのname,テーブルCのnameをcombo boxで表示したとき、Data errorが発生しました。

    Bのnameはきちんと表示されましたが、Cのnameはまったく表示されない状態です。

    ひょっとすると私が上で書いたことは忘れて下さい状態かもしれませんね。以下のように解決策を想像しましたが、合っていますでしょうか?

    DataGridViewにバインドするのはあくまでテーブルAのみ。b_id、c_idはコンボボックス列であり、それぞれのコンボボックスのデータソースはそれぞれテーブルBとテーブルCである。つまり、DataGridViewに表示されるテーブルBとテーブルCのコンボボックス列のコンボボックスのデータソース用に、それぞれデータテーブルを作成するということです。

    (参考)
    DataGridView と データベース と Combobox(コンボボックス)
    http://blog.syo-ko.com/?eid=894

     


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

     


    2012年1月12日 1:52
    モデレータ
  • TableAdapterを用いているのであれば、ストアドの中でケース分けして処理してあげた方が個人的には綺麗な気がします。

    • 回答としてマーク tanaka0011 2012年1月12日 12:49
    2012年1月12日 4:21
  • 更新対象はA,B,C全てとなります。基本的にはAだけなのですが、Bテーブルにないnameを登録したいとき、テキスト入力で入力するとテーブルBにも登録される、というものを作成したいと考えています。

    これを実現しようとすると一気に難易度が高くなります。かなりいろいろな知識を総合的に動員する必要があります。また、DataGridViewの行の中で選択するコンボボックスに自由に値を追加することを許した場合、あっという間にコンボボックスのItem数が多くなり、運用に耐えられなくなりませんか? 耐えられなくなるほど増えるのであれば、別のインターフェースを考える必要がありますし、耐えられるほど滅多に増えないのであれば、テーブルBをマスター登録画面でメンテナンスできるようにするだけで良いと思います。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク tanaka0011 2012年1月12日 12:49
    2012年1月12日 4:30
    モデレータ

すべての返信

  • 質問がよく分かっていませんが・・・

    テーブル 2 つの例ですが、以下のページが参考になりませんか?

    10 行でズバリ !! 非接続型のデータ アクセス (ADO.NET) (C#)
    http://code.msdn.microsoft.com/windowsdesktop/10-ADONET-C-cbfe7688

     

    2012年1月11日 11:50
  • DataGridViewに複数テーブルの参照した場合、Updateメソッドが使えないため、

    更新と登録部分で足踏みしています。

    更新対象となるのはテーブルAだけでしょうか? また、TableAdapterを使用されているのでしょうか? であれば、joinを使わずにSQL文を書いて下さい。
    例えば、

    select a.ID, a_name,
        (select b.b_name from テーブルB b where b.ID = a.ID) b_name,
        (select c.c_name from テーブルC c where c.ID = a.ID) c_name
    from テーブルA
    
    のように書くと、Updateメソッドが使用できるようになります。

    DataGridViewにはテーブルAのデータソースをバインドしています。テーブルAの内容に加えて、

    テーブルBのname,テーブルCのnameをcombo boxで表示したとき、Data errorが発生しました。

    Bのnameはきちんと表示されましたが、Cのnameはまったく表示されない状態です。

    ひょっとすると私が上で書いたことは忘れて下さい状態かもしれませんね。以下のように解決策を想像しましたが、合っていますでしょうか?

    DataGridViewにバインドするのはあくまでテーブルAのみ。b_id、c_idはコンボボックス列であり、それぞれのコンボボックスのデータソースはそれぞれテーブルBとテーブルCである。つまり、DataGridViewに表示されるテーブルBとテーブルCのコンボボックス列のコンボボックスのデータソース用に、それぞれデータテーブルを作成するということです。

    (参考)
    DataGridView と データベース と Combobox(コンボボックス)
    http://blog.syo-ko.com/?eid=894

     


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

     


    2012年1月12日 1:52
    モデレータ
  • 回答ありがとうございます。

    参考ページですが、既に参考にさせて頂いておりまして、

    その方法で、テーブルのリレーションシップを作成しました。

    回答ありがとうございました。

    2012年1月12日 2:09
  • 回答ありがとうございます。

    TableAdapterは使用しています。
    更新対象はA,B,C全てとなります。基本的にはAだけなのですが、Bテーブルにないnameを登録したいとき、テキスト入力で入力すると、
    テーブルBにも登録される、というものを作成したいと考えています。
    なので、回答いただいた上記の方法を使ってみたいと思います。
    回答ありがとうございました。
    2012年1月12日 2:15
  • TableAdapterを用いているのであれば、ストアドの中でケース分けして処理してあげた方が個人的には綺麗な気がします。

    • 回答としてマーク tanaka0011 2012年1月12日 12:49
    2012年1月12日 4:21
  • trapemiyaさんの方法で、DataGridViewの表示は出来ました。

    DataGridViewの下に選択した行の内容を表示して、

    そこで、変更、更新を行うのですが、

    そこで、テーブルBのnameのコンボボックス、テーブルBのnameのコンボボックス

    が必要となります。

     

    (テーブルA)Adapter.Fill(); (テーブルB)Adapter.Fill(); (テーブルC)Adapter.Fill();

    の順番で行うと、テーブルA、テーブルBのnameのコンボボックスは表示されるのですが、

    テーブルCのnameのコンボボックスは表示されません。

     

    まず、順番としては、親テーブルのFill()を先にするのが正しいと考え、

    (テーブルB).Adapter.Fill()と(テーブルC)Adapter.Fill()を行い、(テーブルA)Adapter.Fill()を

    行ったところ、テーブルBのコンボボックスのみ内容が表示されたので、

    (テーブルA)Adapter.Fill(); (テーブルB)Adapter.Fill(); (テーブルC)Adapter.Fill();の順番に

    変更しました。

    多分、原因としては、この辺なのかなと考えているのですが、アドバイスをすみませんが、よろしくお願いします。

     

    2012年1月12日 4:28
  • 更新対象はA,B,C全てとなります。基本的にはAだけなのですが、Bテーブルにないnameを登録したいとき、テキスト入力で入力するとテーブルBにも登録される、というものを作成したいと考えています。

    これを実現しようとすると一気に難易度が高くなります。かなりいろいろな知識を総合的に動員する必要があります。また、DataGridViewの行の中で選択するコンボボックスに自由に値を追加することを許した場合、あっという間にコンボボックスのItem数が多くなり、運用に耐えられなくなりませんか? 耐えられなくなるほど増えるのであれば、別のインターフェースを考える必要がありますし、耐えられるほど滅多に増えないのであれば、テーブルBをマスター登録画面でメンテナンスできるようにするだけで良いと思います。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク tanaka0011 2012年1月12日 12:49
    2012年1月12日 4:30
    モデレータ

  • これを実現しようとすると一気に難易度が高くなります。かなりいろいろな知識を総合的に動員する必要があります。また、DataGridViewの行の中で選択するコンボボックスに自由に値を追加することを許した場合、あっという間にコンボボックスのItem数が多くなり、運用に耐えられなくなりませんか? 耐えられなくなるほど増えるのであれば、別のインターフェースを考える必要がありますし、耐えられるほど滅多に増えないのであれば、テーブルBをマスター登録画面でメンテナンスできるようにするだけで良いと思います。

     


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

    trepemiya様、回答ありがとうございます。

    難易度が高いことだったんですね。

    少しやり方を変えてみたいと思います。

    回答ありがとうございました。

    2012年1月12日 12:48