none
Insertの際にDataViewのデータが2つ増えます RRS feed

  • 質問

  • 長いこと初心者です。

    ADO.NET で1行のデータを追加しようとしています。理解不足のためか、下記のようなコードでInsertCommandを実行すると、DataViewのデータ数が1行でなく、2行増えてしまいます。

    DataRow row;

    cmd = new SqlCommand("INSERT INTO ...

    da.InsertCommand = cmd;

    row = ds.Tables["Test"].NewRow();

    ds.Tables["Test"].Rows.Add(row);

    da.Update(ds, "Test");

    dv = ds.Tables["Test"].DefaultView;
    dataGrid.DataSource = dv;

    こんなコードです。

    このため、dataGridには追加したデータのほかに、空のデータ行が追加されます。

    この辺のロジックがわからないので、どなたか教えていただきたいのです。

    2007年2月11日 4:14

回答

  • DataGridViewと、DataTable、データベースのテーブルの違いをまずはしっかりと理解しましょう。それがわかれば、何をやればいいのかが、自然にわかってきます。

    DataGridViewにデータを持ってくる時の一般的な流れは、以下のようになります。
    1.データベースに接続する。
    2.データベースのテーブルからデータ(レコード)を抽出し、それをDataTableに入れる。
    3.データベースとの接続を切る。
      この時点で、DataTableとデータベースのテーブルは何の関係も無くなります。
      言わば、コピー先とコピー元の関係です。ここを理解することが最も重要です。
    4.DataGridViewにDataTable(DataView)をバインドする。

    さて、SqlCommandでinsert文を発行するというのは、データベースのテーブルに対してレコードを追加するということです。
    追加した後に、上記の1から4を行えば、DataGridViewには新しい行が表示されます。

    また、DataGridViewでデータの追加や編集、削除を行った場合、それはDataTableに対して行われています。前述したように、DataTableとデータベースのテーブルとは連動していませんので、DataTableの内容をデータベースに書き戻す必要があります。これを行うが、DataAdapter.Updateメソッドです。

    2007年2月12日 2:46
    モデレータ

すべての返信

  • 多分※1



    row = ds.Tables["Test"].NewRow();
    ds.Tables["Test"].Rows.Add(row);

     

    この部分が必要ないでしょう。

    以下余談ですが。
    INSERT の SQL 文に何て書いてあるのかわからないので何とも言えませんが、SqlDataAdapter はそういう風に使うものではないかな、と思います。

    ※1 多分と書いたのは、ds や da が何かはっきりわからないので私の予想で書いているからです。

    2007年2月11日 4:35
  • row = ds.Tables["Test"].NewRow();
    ds.Tables["Test"].Rows.Add(row);

    のほうがデータベース負荷かけないでしょう。

    InsertCommand は設定するにしても、上記の場合はまだ DataSet 上にしかないので、最終的に DataAdapter.Update でRDBMS に書き込むことが重要でしょう。

    2007年2月11日 5:19
  • お世話になります。

    da.SelectCommand = cmd; 以下は、

    cmd = new SqlCommand("INSERT INTO Test" +  
                                " (Date, InputTime, UpdateTime, " +
                                "IsToDo, IsDone, Title, Contents, CategoryCode" + 
                                ") VALUES (@Date, @InputTime, @UpdateTime, " +
                                "@IsToDo, @IsDone, @Title, @Contents, @CategoryCode)", cn);

    cmd.Parameters.Add(
                                "@Date", SqlDbType.DateTime, 8, "Date");

    cmd.Parameters.Add(
                                "@InputTime", SqlDbType.DateTime, 8, "InputTime");

    以下、同様にパラメータを追加。そして、

    da.InsertCommand = cmd;

    row = ds.Tables["Test"].NewRow();

    DateTime dt = new DateTime(
                                Convert.ToInt32(yearBox.Text),
                                Convert.ToInt32(monthBox.Text),
                                Convert.ToInt32(dayBox.Text));

    row["Date"] = dt;

    row["InputTime"] = DateTime.Now.ToString();

    row["CategoryCode"] = int.Parse(categoryCodeBox.Text);

    以下同様に(DataRowにカラムの値を与えます...)と続き、

    ds.Tables["Test"].Rows.Add(row);

    da.Update(ds, "Test");

    というコードです。

    この最後の「da.Update(ds, "Test");」は

    「DataAdapter.Update でRDBMS に書き込むこと」とは違うのでしょうか?

    この辺り、まだ長いこと飲み込めないのです(理屈を省いて鵜呑みのままなので、ずっと初心者のままで恥ずかしいです)。RowStateなどと関連があるのでしょうか?

    --------------追記ですが-------------

    ds = null;
    ds = new DataSet("TestDataBase");

    として、いったんDataSetを解放してから再度新しいDataSetを作成すれば、問題なく処理できます(これは、当たり前でしょうけれど)。

    2007年2月11日 8:38
  • DataGridViewと、DataTable、データベースのテーブルの違いをまずはしっかりと理解しましょう。それがわかれば、何をやればいいのかが、自然にわかってきます。

    DataGridViewにデータを持ってくる時の一般的な流れは、以下のようになります。
    1.データベースに接続する。
    2.データベースのテーブルからデータ(レコード)を抽出し、それをDataTableに入れる。
    3.データベースとの接続を切る。
      この時点で、DataTableとデータベースのテーブルは何の関係も無くなります。
      言わば、コピー先とコピー元の関係です。ここを理解することが最も重要です。
    4.DataGridViewにDataTable(DataView)をバインドする。

    さて、SqlCommandでinsert文を発行するというのは、データベースのテーブルに対してレコードを追加するということです。
    追加した後に、上記の1から4を行えば、DataGridViewには新しい行が表示されます。

    また、DataGridViewでデータの追加や編集、削除を行った場合、それはDataTableに対して行われています。前述したように、DataTableとデータベースのテーブルとは連動していませんので、DataTableの内容をデータベースに書き戻す必要があります。これを行うが、DataAdapter.Updateメソッドです。

    2007年2月12日 2:46
    モデレータ
  • ははぁ。

    DataAdapter.UpdateメソッドはDataTableの値を変更する操作をするのではなくて、

    データベースを変更するというわけですね!

    ということで、データベースのレコードを取り込むのは、trapemiyaさんご指摘の1から4の操作なのですね。言われてみると当然のことのようで、目玉がクリクリになり、なんだかますます恥ずかしくなります...。が、これが長期初心者から脱出の糸口となるかも知れず、感謝感激です。

    しっかし、DataAdapterにつまづいているうちに、C#の文法を忘れていったり、C#の文法を復習しているうちにDataGridViewの操作につまづいたり、SQL Server の操作に滅入ったりと、果てしないです...

    2007年2月12日 6:12