none
VB2008のDataAdapterでデータ件数が正しく取得できない RRS feed

  • 質問

  • VB2008のDataAdapterを使ってますが、Form1からForm2を表示させていますが、Form2で取得しているT_Zipの件数が本来は1件なのですが、Form1からForm2を呼び出すたび件数が1,2,3・・と増えて行きます。Adapterなど開放していますし・・。申し訳ありませんがご教授いただけませんでしょうか。

    <Form1>
        Private Sub Form1_Load(略)
            Dim strCnn As String

            strCnn = /* PostgreSQL接続文字 */
            Cnn = New NpgsqlConnection(strCnn) <-- モジュールでPublicしてます
        End Sub

        Private Sub ShowForm_Click(略)
            Form2.ShowDialog()
        End Sub

    <Form2>
        Private npgDataSet As DataSet = New DataSet
        Private npgDataAdapter As New Npgsql.NpgsqlDataAdapter
        Private npgTrans As NpgsqlTransaction
        Private npgBuilder As Npgsql.NpgsqlCommandBuilder

        Private Sub frmZip_FormClosing(略)
            npgBuilder.Dispose()
            npgDataSet.Dispose()
            npgDataAdapter.Dispose()
        End Sub

        Private Sub frmZip_Load(略)

            With npgDataAdapter
                .SelectCommand = New NpgsqlCommand()
                With .SelectCommand
                    .CommandText = CommandType.Text
                    .CommandText = "SELECT ZipCode, Address FROM T_Zip;"
                    .Connection = Cnn
                End With
            End With
           
            npgBuilder = New Npgsql.NpgsqlCommandBuilder(npgDataAdapter)
            npgDataAdapter.FillLoadOption = LoadOption.OverwriteChanges
            npgDataAdapter.Fill(npgDataSet, "T_Zip")
            Label1.Text = "登録件数:" & npgDataSet.Tables("T_Zip").Rows.Count.ToString
        End Sub

    2010年10月16日 7:08

回答

  • 「何度開いても毎回同じインスタンスを開いていることになります」について補足をお願いできませんか。
    基本的に使用しなくなったインスタンスは使用しなくなったら開放すると思っています。
    よってDispose()で開放しているつもりで、未使用(メモリーから消える)認識でいます。
    つまり、Form2を呼び出すたび新しいインスタンスで開かれると思っていました。
    でも違うのですよね。

    ShowDialogで表示したフォームは、フォームを閉じてもインスタンスが残り続けます。既定のインスタンスの動作は、そのインスタンスが無ければ新たにインスタンスを作成し、あればそのインスタンスを利用します。以上を合わせて考えると、ShowDialogしてDisposeしなければ、毎回同じインスタンスが使用されることになります。SurferOnWwwさんが既に書かれているように、Form2をDisposeすればうまくいくと思います。DisposeはUsing句で行なうが便利で確実です。ShowDialogを使う時にはUsing句とセットで使うことを覚えておかれると良いでしょう。これは既定のインスタンスを使う場合も、そうではなく普通にNewしてForm2を表示する場合も当てはまります。

    既定のインスタンスについては以下が参考になります。

    Visual Basic 2005 の My 機能の検証
    http://msdn.microsoft.com/ja-jp/library/ms379610(VS.80).aspx

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年10月17日 8:54
    モデレータ

すべての返信

  •     Private Sub ShowForm_Click(略)
            Form2.ShowDialog()
        End Sub


    ざっと見たところ、Form2をNewしてインスタンスを作成していませんから、Form2は既定のインスタンスが使用されていると思われます。したがってForm2を何度開いても毎回同じインスタンスを開いていることになります。その結果、毎回同じT_ZipにFillされ、Fillされたレコードが累積されていっている状態だと思います。よってこれを防ぐには、Form2をNewして新たにインスタンスを作成した後にShowDialogするか、Fillする前にT_Zipが存在していればその中身をクリア(DataTable.Clear()メソッド)する必要があります。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年10月16日 8:27
    モデレータ
  • ありがとうございます。
    「何度開いても毎回同じインスタンスを開いていることになります」について補足をお願いできませんか。
    基本的に使用しなくなったインスタンスは使用しなくなったら開放すると思っています。
    よってDispose()で開放しているつもりで、未使用(メモリーから消える)認識でいます。
    つまり、Form2を呼び出すたび新しいインスタンスで開かれると思っていました。
    でも違うのですよね。
    勉強不足ですいませんが、再度ご教授願えればと思います。
    2010年10月17日 1:09
  • > よってDispose()で開放しているつもりで、未使用(メモリーから消える)認識でいます。

    From2 自体は Dispose されてないようですが、そうだとするとそこに問題があるので
    はないですか?

    以下のページのサンプルコードにあるように、毎回 New して新たにインスタンスを作
    成し、使い終わったら Dispose するようにしたら期待した結果になりませんか(今回
    のように、DataSet や DataAdapter を繰り返し使うのにその方法がよいかどうかは別
    問題として)?

    Form.ShowDialog メソッド
    http://msdn.microsoft.com/ja-jp/library/c7ykbedk(v=VS.100).aspx

    2010年10月17日 6:06
  • 「何度開いても毎回同じインスタンスを開いていることになります」について補足をお願いできませんか。
    基本的に使用しなくなったインスタンスは使用しなくなったら開放すると思っています。
    よってDispose()で開放しているつもりで、未使用(メモリーから消える)認識でいます。
    つまり、Form2を呼び出すたび新しいインスタンスで開かれると思っていました。
    でも違うのですよね。

    ShowDialogで表示したフォームは、フォームを閉じてもインスタンスが残り続けます。既定のインスタンスの動作は、そのインスタンスが無ければ新たにインスタンスを作成し、あればそのインスタンスを利用します。以上を合わせて考えると、ShowDialogしてDisposeしなければ、毎回同じインスタンスが使用されることになります。SurferOnWwwさんが既に書かれているように、Form2をDisposeすればうまくいくと思います。DisposeはUsing句で行なうが便利で確実です。ShowDialogを使う時にはUsing句とセットで使うことを覚えておかれると良いでしょう。これは既定のインスタンスを使う場合も、そうではなく普通にNewしてForm2を表示する場合も当てはまります。

    既定のインスタンスについては以下が参考になります。

    Visual Basic 2005 の My 機能の検証
    http://msdn.microsoft.com/ja-jp/library/ms379610(VS.80).aspx

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年10月17日 8:54
    モデレータ
  • HELPを見るとVB6とはだいぶ異なるようですね。

    勉強になりました。ありがとうございました。もっと勉強が必要なようです。

    感謝です。

     

    2010年10月17日 11:06