none
データテーブルのデータをデータベースのテーブルにINSERTするにあたり RRS feed

  • 質問

  • データベースのテーブル構造と同じデータテーブルがあり、データテーブルのデータをデータベースに反映したいと思っています。
    データベースのテーブルのデータは、まだ一行もありません、
    また、PrimaryKey はデータテーブルにも、データベースのテーブルにも設定していません。
    方法は、
            string strTableName = "テーブル名";
            DataSet dSet = new DataSet("データベース名");
            SqlDataAdapter da = new SqlDataAdapter();
            SqlConnection cn = new SqlConnection(connStr);
            // ----------------- connStr など省略
            cn.Open();
            for (int i = 0; i < dSet.Tables[strTableName].Rows.Count; i++)
            {
                strInsCmd = "INSERT INTO " + strTableName +
                    " (ID, Address, Telephone, Fax)" +
                    " VALUES ('" +
                    dSet.Tables[strTableName].Rows[i]["ID"] + "', '" +
                    dSet.Tables[strTableName].Rows[i]["Address"] + "', '" +
                    dSet.Tables[strTableName].Rows[i]["Telephone"] + "', '" +
                    dSet.Tables[strTableName].Rows[i]["Fax"] + "'" +
                    ")";
            }
            da.InsertCommand = new SqlCommand(strInsCmd, cn);
            da.Update(dSet.Tables[strTableName]);
            cn.Close();

    という方法なのですが、
    データベースのテーブルを開くと、データテーブルの1行目だけのデータテーブルの行数だけ
    データベースのテーブルに入っていきます。
    なぜ、1行目だけしかデータテーブルに転記しないのでしょうか?
    ループ中には、データテーブルの1行目から最後の行まで順次追加が進んでいるように見えるのですが。

    どうすると、データベースのデータが、データテーブルに正常に追加されるのかと、
    何がいけないのかを教えていただきたいと思います。

    よろしくお願いします。

    • 編集済み yasheeki 2009年12月13日 14:14 追加
    2009年12月13日 8:59

回答

  • クラスとかの概念をつかむことは、大事なことなのですか。
    DataTableでのどんなコードで何ができるのか、くらいしか意識していりませんで、概念は一切考えずにおりました。
    これが、理解を「浅める」原因だったのでしょうか?

    概念も考えずに理解しようとすることからして、何やら、長ー時間無駄にしていたでしょうか?
    概念(・・・イメージともいう)を掴むことは非常に大事ですよ。

    もっとも最近出版された某書では、Micosoft の設計者たちが、ADO.NET のクラス構成は確かに判りにくかったと白状してるくらいですので、yasheeki さんが混乱するのも無理がないのかもしれません。

    ちなみにここは SQLServer のフォーラムなので、ADO.NET の達人さんはあまり見ておられないようです。
    ADO.NET の詳しい使い方に関する議論は、いったんこのスレを閉じて
    .NET Framework 全般 か Visual C# 等の別のフォーラムに移動した方がよさそうです。

    • 回答としてマーク yasheeki 2009年12月29日 13:13
    2009年12月29日 5:08

すべての返信

  • strInsCmdはループの度に置き換えられています。したがって、ループを抜ける最後の行の内容でinsert文ができあがっています。これを仮にinsert文Aと名付けましょう。
    さて、SqlDataAdapterのUpdateメソッドは、データテーブルの変更を自動的に判断してデータベースへ適切なSQL文を発行し、データベースへデータテーブルの内容を反映させます。この時、データテーブルの新規行に関してはSqlDataAdapterのInsertCommandに設定したSQL文が発行されます。
    したがって、データテーブルに追加した新規行分の先に設定した同じinsert文Aが発行されることになります。この結果が、ご質問で書かれた現象になります。

    以上より、insert文が誤っていることがわかります。以下あたりを参考にして設定してみて下さい。

    DataAdapter によるデータ ソースの更新
    http://msdn.microsoft.com/ja-jp/library/33y2221y(VS.80).aspx

    DataAdapter によるパラメータの使用
    http://msdn.microsoft.com/ja-jp/library/bbw6zyha(VS.80).aspx


    以上を参考にしてコードを修正されると、ループは無くなります。SqlDataAdapterのUpdateメソッドが、データテーブルの行毎にパラメータ値の異なるinsert文を発行し、データテーブルの全ての新規行がデータベースに保存されるからです。

    #SqlDataAdapterを使用しない方法も考えられます。その場合にはループの中で動的にinsert文を作成してSqlCommandのCommandTextにセットし、SqlCommand.ExecuteNonQuery()メソッドを実行することになります。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年12月13日 15:11
  • おおむね trapemiya さんが御指摘のとおりですが、蛇足です。

    一括でインサートするには、以下のように SqlCommandBuilder を使って挿入クエリを自動生成するという方法もあります。
    つーかむしろ推奨!

    ただしこの場合、初期化時の選択クエリと DataTable の列の整合性が取れていることが前提になります。

    例:
    DataTable dt = dSet.Tables[strTableName]);
    SqlDataAdapter da =
        new SqlDataAdapter("select ID, Address, Telephone, Fax from " + strTableName);
    SqlCommandBuilder builder = new SqlCommandBuilder(da);

    ・・・・・・

    da.Update(dt);

    あと主キーが設定されてないということですので、
    行状態をあらかじめ「追加状態」・・・RowState.Added にしておくのも必要かと思われます。
    これは DataRow.SetAdded メソッドで可能です。

    #もう遅いですが、この質問は SQL Server よりも C#のフォーラムに立てた方が良かったですね。

    2009年12月13日 15:31
  • 一括でインサートするには、以下のように SqlCommandBuilder を使って挿入クエリを自動生成するという方法もあります。
    つーかむしろ推奨!
    少し補足をしますと、SqlCommandBuilderを使うためには主キーもしくはユニークな値を持つ列が必要です。主キーが無いということですのでユニークな値を持つ列が必要ですが、もしそれもなければうまくいきません。

    また、SqlCommandBuilderは実行時にSQL文を生成するために、データベースからスキーマ情報を取得するなどの手間が発生します。もっとも人間が無視できるぐらいのパフォーマンスの低下であればさほど気にする必要はないと思いますが、毎回このように解析して同じSQL文を生成するのは、個人的にはあまり面白くありません・・・。あくまで個人的な気持ちの問題なのですが・・・
    なので、SQL文を自動生成させるのであれば、私はSqlDataAdapterをデザイナに張り付けて、そのウィザードでSQL文を事前に生成させてしまうことを好みます。

    私が今回言いたかった補足は、SqlCommandBuilderを使うのはケースバイケースにしましょうということです。
    初心者の方はSqlCommandBuilderでどのようなSQL文が生成されるのかを見ることも参考になると思います。
    SqlCommandBuilder.GetUpdateCommand().CommandText で確認できます。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年12月14日 5:47
  • 解説をありがとうございます。

    ただ、申し訳ないことに、提示したコードが間違っていました。

            da.InsertCommand = new SqlCommand(strInsCmd, cn);
            da.Update(dSet.Tables[strTableName]);

    のコードは、ループ中に入れて実行しました。
    このせいか、実行されるコードがループの最初(i = 0)のときのデータテーブルのデータが
    データベースに反映します。
    しかも、
    i < dSet.Tables[strTableName].Rows.Count
    になるまでの回数ずっと、i = 0 のときと同じデータが繰り返しデータベースに送り込まれます。

    ひょっとすると、
    dSet.Tables[strTableName].Rows[i]["ID"]
    などとしてすぐに(ループ中に)、データベースに転記されたデータテーブルの行データを削除すれば
    次のデータが入るのかも、などと考えていました(試していませんが)。

    ご紹介いただいた
    DataAdapter によるデータ ソースの更新
    DataAdapter によるパラメータの使用
    を拝見させていただきましたが、これがまたなかなかコードに反映させる段階に進んでいかないのです。
    2009年12月15日 11:59
  • >この質問は SQL Server よりも C#のフォーラムに立てた方が良かったですね。

    とのことで、C#のフォーラムに変更していただきたいです。
    主キーを設定してもう一度、試してみようと思います。
    また、DataRow.SetAdded というのをやってみます。
    2009年12月15日 12:11
  • cn.Open();
    のあとのループのコード前に
    da.InsertCommand = new SqlCommand("INSERT INTO " + strTableName +
        " (ID, Address, Telephone, Fax" +
        " VALUES ('@IID, @Address, @Telephone, @Fax')", cn);
    SqlParameter prAddID = da.InsertCommand.Parameters.Add(dSet.Tables[strTableName].Columns["ID"], SqlDbType.Int, 10, "ID");
    というコードを入れてみたところ、
    無効な引数がいくつか含まれているとのメッセージでした。

    なお、このパラメータのsize を 10 としたことには、何の根拠もありません。

    で、次に進みません。

    どうしたものでしょうか?(もう少し、いろいろ試した後で、投稿したかったのですが、締め切られる前がいいかなと......。)
    2009年12月15日 13:11
  • > のコードは、ループ中に入れて実行しました。

    SqlDataAdapter.Update() メソッドは DataSet 、もしくは DataTable に対して一括更新を行うメソッドです。
    ループで一行ずつ回すなら、ここは SqlDataadapter 使わずに SqlCommand.ExecuteNonQuery を使った方がいいかもしれませんね。

    2009年12月15日 13:52
  • 少し補足をしますと、SqlCommandBuilderを使うためには主キーもしくはユニークな値を持つ列が必要です。主キーが無いということですのでユニークな値を持つ列が必要ですが、もしそれもなければうまくいきません。

    また、SqlCommandBuilderは実行時にSQL文を生成するために、データベースからスキーマ情報を取得するなどの手間が発生します。もっとも人間が無視できるぐらいのパフォーマンスの低下であればさほど気にする必要はないと思いますが、毎回このように解析して同じSQL文を生成するのは、個人的にはあまり面白くありません・・・。あくまで個人的な気持ちの問題なのですが・・・
    なので、SQL文を自動生成させるのであれば、私はSqlDataAdapterをデザイナに張り付けて、そのウィザードでSQL文を事前に生成させてしまうことを好みます。

    私が今回言いたかった補足は、SqlCommandBuilderを使うのはケースバイケースにしましょうということです。
    そうですね。
    確かに今回のケースなら Update/Delete は効果ないのは判ります。
    しかし Insert だけなら使えると思っていたのですが、違いましたっけ?
    2009年12月15日 13:57
  • cn.Open();
    のあとのループのコード前に
    da.InsertCommand = new SqlCommand("INSERT INTO " + strTableName +
        " (ID, Address, Telephone, Fax" +
        " VALUES ('@IID, @Address, @Telephone, @Fax')", cn);
    SqlParameter prAddID = da.InsertCommand.Parameters.Add(dSet.Tables[strTableName].Columns["ID"], SqlDbType.Int, 10, "ID");
    というコードを入れてみたところ、
    無効な引数がいくつか含まれているとのメッセージでした。

    パラメタライズドクエリの生成の仕方が間違ってます。
    第一引数にパラメータを指定しないと駄目ですよ。以下例です。

    SqlCommand command = new SqlCommand(strInsCmd, cn);
    command.Parameters.Add(new SqlParameter("ID", dSet.Tables[strTableName].Rows[i]["ID"] );
    ・・・・・・・
    da.InsertCommand = command;


    あと今まで提示頂いたコードをよ~く見ると、突っ込みどころが多いようです。

    > " VALUES ('@IID, @Address, @Telephone, @Fax')", cn);

    なぜにシングルクォーテーションで囲んでいるの?とか

    > dSet.Tables[strTableName].Columns["ID"]

    これではDataColumn オブジェクトを参照してたりとか、クエリもよくよく見たら括弧が閉じてない!とか、

    もう少し ADO.NET を基礎から勉強し直した方がいいような気がしますね・・・(^ω^;
    2009年12月15日 14:38
  • 試しに主キーのないテーブルを二つ用意し、データの移動を行ってみました。
    Customers1 は主キーなしインデックスなしで重複データを用意し、
    Customers2 は Customers1 と全く同じスキーマですがデータは入っていません。

    private void button1_Click(object sender, EventArgs e) {
        SqlConnection cn = 
    	new SqlConnection("Data Source=hilapon;Initial Catalog=Test;Integrated Security=True");
        try {
            cn.Open();
            try {
                // コピー元のテーブルを生成
                SqlCommand cmd1 = 
    		new SqlCommand("SELECT Id, Address, Telephone, Fax From Customers1", cn);
                SqlDataAdapter adapter1 = new SqlDataAdapter(cmd1);
                DataSet ds = new DataSet();
                adapter1.Fill(ds);
                DataTable dt1 = ds.Tables[0];
    
                // コピー先のテーブルを生成
                SqlCommand cmd2 = 
    		new SqlCommand("SELECT Id, Address, Telephone, Fax From Customers2", cn);
                SqlDataAdapter adapter2 = new SqlDataAdapter(cmd2);
    
                // CommandBuilder を生成
                SqlCommandBuilder builder = new SqlCommandBuilder(adapter2);
                DataTable dt2 = new DataTable();
                adapter2.Fill(dt2);
    		
                // LoadDataRow でコピー先へデータを設定


    dt2.BeginLoadData(); foreach (DataRow row in dt1.Rows) { dt2.LoadDataRow(row.ItemArray, false); }


    dt2.EndLoadData();
    // 更新 adapter2.Update(dt2); } catch (Exception ex) { throw ex; } finally { cn.Close(); } } catch (Exception ex) { throw ex; } }

    これで、データが移動できたことを確認できました。
    ちなみに環境は Windows XP SP3/VS 2008 SP1/SQLServer 2008 Web Version です。

    あと・・・

    >この質問は SQL Server よりも C#のフォーラムに立てた方が良かったですね。

    とのことで、C#のフォーラムに変更していただきたいです。

    これは フォーラムオペレータの方にお任せしましょう。
    • 編集済み ひらぽん 2009年12月16日 1:07 コードの修正、BeginLoadData() を忘れてた
    • 回答としてマーク yasheeki 2009年12月17日 14:21
    • 回答としてマークされていない yasheeki 2009年12月20日 11:50
    2009年12月15日 16:10
  • ありがとうございます。

    ご提示のコードで(簡単に)テーブルデータの移動がデータベースに反映されました。
    しかし、私に内容が理解できていないのは、否めません。

    BeginLoadData というのも初耳でした。
    これは、CommandBuilder を利用する方法ですね?
    非常に簡単にできるので驚きました。

    CommandBuilder も、デザイナーのウィザードも利用しない方法というのもあるのでしょうか?
    それとも、奨められないものなのでしょうか?
    この場合は、コードが面倒になるのでしょうか?

    ADO.NETの初歩からして「分かってない」のが、歯がゆくてしょうがありません(長期初歩止まりで悔しいところなのです)。
    2009年12月16日 14:33
  • こんな機能もあります。

    bcp ユーティリティ
    http://msdn.microsoft.com/ja-jp/library/ms162802.aspx

    2009年12月16日 16:04
  • BeginLoadData というのも初耳でした。
    これは、CommandBuilder を利用する方法ですね?
    非常に簡単にできるので驚きました。

    この場合、BeginLoadData  よりも LoadDataRow メソッドがポイントですね。
    BeginLoadData で準備、LoadDataRow メソッドで行データをテーブルにロード、EndLoadData で完了という流れになります。
    ちなみに BeginLoadData ・ EndLoadData を忘れて LoadDataRow を実行すると、パフォーマンスが著しく遅くなります。

    また CommandBuilder  と LoadDataRow はあまり関係ありません。
    CommandBuilder  はむしろ SqlDataAdapter.Update を使う際に使います。


    CommandBuilder も、デザイナーのウィザードも利用しない方法というのもあるのでしょうか?
    それとも、奨められないものなのでしょうか?
    この場合は、コードが面倒になるのでしょうか?

    認められてないことはないです。まぁ、ケースバイケースですね。
    例えばコードが冗長になりますが普通にクエリを投げてやるとか、後はストアドを実行させるという手も考えられます。
    最近では Linq To Dataset や Entity Framework を使った更新方法もあるようです。

    2009年12月16日 23:02
  • ADO.NETの初歩からして「分かってない」のが、歯がゆくてしょうがありません(長期初歩止まりで悔しいところなのです)。
    CommandBuilderやウイザードを使うと確かに楽に実現できてしまいますが、これらに頼ってばかりいると一向に理解が進まず、いつまでも歯がゆさは無くらないと思います。CommandBuilderやウイザードはADO.NETをラップして楽に使うものであり、ADO.NETそのものの勉強にはならないからです。ついでに言えばTableAdapterも同じです。便利になればなるほど基本的なことを知る必要が無くなり、冗長度の高いSQL文を発行し続けたり、応用が利かなくなってしまいます。ADO.NETやSQL文をちゃんと勉強すれば良いということに気づけばまだ良いのですが、気づかなければ初心者の方はそこから先に進めなくなってしまうでしょう。特にSQL文を勉強することは大事です。そうでなければ、ADO.NETを直接扱うことはほぼ無理です。

    ADO.NETを勉強できる記事はネット上にもいくつかありますが、お勧めは書籍で体系的にじっくり腰を据えて学ぶことです。少々高い本ですが、以下の本は私にとってかなり役立ちました。実際に私が読んだのは以前のバージョンである「プログラミングMicrosoft ADO.NET」ですが、著者は同じDavid Sceppaさんです。

    プログラミングMicrosoft ADO.NET2.0
    http://ec.nikkeibp.co.jp/item/books/597000.html
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク yasheeki 2009年12月17日 14:22
    • 回答としてマークされていない yasheeki 2009年12月20日 11:50
    2009年12月17日 1:41
  • ADO.NET は、思った以上に範囲が広いのですね。
    しかも、やり方が何通りもあるという、曲者でもありますね。
    どの方法がよいかは、やはり大体のことが理解できてからしか分からないのだろうと感じます。

    今の自分には、どれがよいのかまだつかめないのですが、あんな方法も、こんな方法もあるということが分かっただけでも勉強になります。
    ありがとうございます。
    2009年12月17日 14:09
  • 何やら、またしても別の機能があるとのことで、また深呼吸中です。
    大食い選手権のようですが、勉強になります。
    2009年12月17日 14:11
  • やはり、基本が最も大事のようです。
    ただ、基本が一番難しいようでもありますね。

    >書籍で体系的にじっくり腰を据えて学ぶ
    とは、ごもっともです。
    一からもう一度勉強しなおしてみようと思っています。

    ただ、もう何度も一から勉強してみましたが、なかなか理解まで届かないので、やっぱり根本的に能力が劣るのかなと、がっかり感は残ります。
    なにしろ、ADO.NET は、やっぱり難しいのです。
    じつは、プログラミングMicrosoft ADO.NET2.0 も読んでいますが、これまた広範囲で、理解すべき本筋が絞れないでいるところです。
    (愚痴が多くてゴメンナサイ)。

    でも、やはり基本を押さえることを念頭にあきらめずに頑張ります。
    本当にありがとうございます。感謝しています。
    2009年12月17日 14:21
  • いったん、今回のスレッドを解答としてマークしました。
    が、自分の中で未解決の問題を、上っ面だけ分かったというだけで、解決としてマークしてよいのだろうか、というわだかまりを感じて、解決としてのマークを解除しました。
    問題は、解決されていませんでした。

    一つは、ひろぽんさんからいただいた解答ですが、
     これは、Increment列の値が、元の値と違ってしまいますので、元のデータテーブルのままデータを移行することが出来ていないままでしたので、これで解決とするには、このスレッドを参考にした人に対して中途半端すぎて申し訳ないと感じたことです。
    また、
     trapemiyaさんから頂いた回答で、
     DataAdapter によるデータ ソースの更新
    http://msdn.microsoft.com/ja-jp/library/33y2221y(VS.80).aspx

    DataAdapter によるパラメータの使用
    http://msdn.microsoft.com/ja-jp/library/bbw6zyha(VS.80).aspx

    との、ご回答ですが、これは解決というよりも、解決への指針というレベルなので、解決としてマークするにはまだ奥が深すぎるということです。

    で、結局自分で解答レベルの理解ができたかというと、まだまだ理解できていないというのが正直なところです。
    ゆえに、今回の解決としてのマークを外させていただきました。(実は、分からないことが多すぎて混乱しているというのが現実です)

    2009年12月20日 12:04
  • 一つは、ひろぽんさんからいただいた解答ですが、
     これは、Increment列の値が、元の値と違ってしまいますので、元のデータテーブルのままデータを移行することが出来ていないままでしたので、これで解決とするには、このスレッドを参考にした人に対して中途半端すぎて申し訳ないと感じたことです。
    えと・・・コピー先のID 列の値が、コピー元と変わってしまっているということでしょうか?
    私が提示したサンプルコードでは、「主キーなし・インデックスなし・重複データあり」を想定したテーブルですので
    他のテーブルからインクリメント列にデータを丸々コピーするには、当然事前に対処する必要があります。


    > 結局自分で解答レベルの理解ができたかというと、まだまだ理解できていないというのが正直なところです。
    > (実は、分からないことが多すぎて混乱しているというのが現実です)

    なんか判るような判らないような・・・(苦笑)

    まぁ、今までの自分の体験を超えたアーキテクチャーに出会うと、話を聞いてもすぐには理解できないのも当然かとも思います。
    私もかって VC++ のプロジェクトを初めて手掛けた頃は、
    今まで使っていた言語と全く違う構文や概念に、理解するのに半年以上も要しました。(^ω^;

    また MSDN は基本的に機械翻訳だと聞きましたので、一般の日本人には取っつきにくい文章になってるせいか
    読んでいてもイマイチ頭に入ってこないような感があります。
    (私の読解力不足のせいもありますが。)

    もっとも全く判らないというわけではないと思いますので、いっぺんに全て理解しようとせずに
    まずは理解できる概念から、少しずつ各個撃破で理解を深めていった方がいいかと思います。


    ちなみに DataTable ってどういうクラスか判りますか?

    2009年12月21日 1:36
  • >ちなみに DataTable ってどういうクラスか判りますか?

    ってことで、ギョッとしました。
    System.Data名前空間にあり、
    DataRowCollection、DataColumnsCollectionを持っており、
    RowsプロパティとColumnsプロパティを持ち、
    RowChangedなどのイベントがあり...
    ええっと。
    っという感じで、クラスとかは意識しておりませんでした。

    クラスとかの概念をつかむことは、大事なことなのですか。
    DataTableでのどんなコードで何ができるのか、くらいしか意識していりませんで、概念は一切考えずにおりました。
    これが、理解を「浅める」原因だったのでしょうか?

    概念も考えずに理解しようとすることからして、何やら、長ー時間無駄にしていたでしょうか?
    2009年12月24日 12:39
  • クラスとかの概念をつかむことは、大事なことなのですか。
    DataTableでのどんなコードで何ができるのか、くらいしか意識していりませんで、概念は一切考えずにおりました。
    これが、理解を「浅める」原因だったのでしょうか?

    概念も考えずに理解しようとすることからして、何やら、長ー時間無駄にしていたでしょうか?
    概念(・・・イメージともいう)を掴むことは非常に大事ですよ。

    もっとも最近出版された某書では、Micosoft の設計者たちが、ADO.NET のクラス構成は確かに判りにくかったと白状してるくらいですので、yasheeki さんが混乱するのも無理がないのかもしれません。

    ちなみにここは SQLServer のフォーラムなので、ADO.NET の達人さんはあまり見ておられないようです。
    ADO.NET の詳しい使い方に関する議論は、いったんこのスレを閉じて
    .NET Framework 全般 か Visual C# 等の別のフォーラムに移動した方がよさそうです。

    • 回答としてマーク yasheeki 2009年12月29日 13:13
    2009年12月29日 5:08
  • 概念も考えずに理解しようとすることからして、何やら、長ー時間無駄にしていたでしょうか?

    概念がわからなければ理解できないと思いまよ。何度も私が言い続けていることですが、ADO.NETに限らず.NET Frameworkの設計者たちは必ず意味を持って設計しています。つまり、必ずその存在理由があるのです。残念ながらMSDNライブラリにおけるそれぞれの存在理由に関する説明は不十分ですが、それでも昔よりはだいぶ良くなってきています。
    なぜ、何の目的のためにDataSetがあるのか? DataAdapterがあるのか? 自分で本を書かれるつもりで一度まとめてみられると良いと思います。そうすることで自分の理解であやふやなところも見つかります。ネットで検索したり、テストコードを書いて確かめることも自信につながります。そしてその書かれたものは、迷ったり忘れた時に必ず役に立ちます。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年12月29日 7:36
  • 概念がわからなければ理解できないと思いまよ。何度も私が言い続けていることですが、ADO.NETに限らず.NET Frameworkの設計者たちは必ず意味を持って設計しています。つまり、必ずその存在理由があるのです。残念ながらMSDNライブラリにおけるそれぞれの存在理由に関する説明は不十分ですが、それでも昔よりはだいぶ良くなってきています。
    なぜ、何の目的のためにDataSetがあるのか? DataAdapterがあるのか? 自分で本を書かれるつもりで一度まとめてみられると良いと思います。そうすることで自分の理解であやふやなところも見つかります。ネットで検索したり、テストコードを書いて確かめることも自信につながります。そしてその書かれたものは、迷ったり忘れた時に必ず役に立ちます。

    trapemiya さんの話に蛇足ですが、最近こんな本読んでます。

    .NETのクラスライブラリ設計

    翻訳や校正に難がありますが、この本を読むと trapemiya さんのおっしゃる

    > .NET Frameworkの設計者たちは必ず意味を持って設計しています。

    ということがよく判ると思います。

    いったん ADO.NET から離れて、オブジェクト指向や .NET の構造に関する本を読みなおすと理解が深まりますよ。
    2009年12月29日 8:17
  • 今回、ADO.NET に関する質問をさせていただいたことで、ためになるご回答をいただき、大変感謝しています。
    私の基礎があやふやなこともあり、せっかくのアドバイスも現在は有効に活用出来ず残念ではありますが、基礎からご指導いただけたことについて頭が下がります。

    なお、今回の質問はいづれ解決していくつもりではありますが、それに際して追加の質問を別途させていただくこともあろうかと思いますが、その節はどうぞよろしくお願いいたします。

    ひらぽんさま、NOBTAさま、trapemiyaさま、有難うございます。
    2009年12月29日 13:11