トップ回答者
VB2008のDataAdapterでデータ件数が正しく取得できない

質問
-
VB2008のDataAdapterを使ってますが、Form1からForm2を表示させていますが、Form2で取得しているT_Zipの件数が本来は1件なのですが、Form1からForm2を呼び出すたび件数が1,2,3・・と増えて行きます。Adapterなど開放していますし・・。申し訳ありませんがご教授いただけませんでしょうか。
<Form1>
Private Sub Form1_Load(略)
Dim strCnn As StringstrCnn = /* PostgreSQL接続文字 */
Cnn = New NpgsqlConnection(strCnn) <-- モジュールでPublicしてます
End SubPrivate 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.NpgsqlCommandBuilderPrivate Sub frmZip_FormClosing(略)
npgBuilder.Dispose()
npgDataSet.Dispose()
npgDataAdapter.Dispose()
End SubPrivate 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
回答
-
「何度開いても毎回同じインスタンスを開いていることになります」について補足をお願いできませんか。
基本的に使用しなくなったインスタンスは使用しなくなったら開放すると思っています。
よって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/
すべての返信
-
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/ -
> よってDispose()で開放しているつもりで、未使用(メモリーから消える)認識でいます。
From2 自体は Dispose されてないようですが、そうだとするとそこに問題があるので
はないですか?以下のページのサンプルコードにあるように、毎回 New して新たにインスタンスを作
成し、使い終わったら Dispose するようにしたら期待した結果になりませんか(今回
のように、DataSet や DataAdapter を繰り返し使うのにその方法がよいかどうかは別
問題として)?Form.ShowDialog メソッド
http://msdn.microsoft.com/ja-jp/library/c7ykbedk(v=VS.100).aspx -
「何度開いても毎回同じインスタンスを開いていることになります」について補足をお願いできませんか。
基本的に使用しなくなったインスタンスは使用しなくなったら開放すると思っています。
よって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/