ADO.NETでテーブル更新するには?

解決


AYAKA  2008-07-14 23:49:15  No: 144941  IP: 192.*.*.*

はじめまして。
ADO.NETでテーブルを更新する方法がよくわかりません。
やりたい事は下記の内容です。

データセットを作成しフォームに登録する
顧客テーブルの内容がDataGridViewに表示される

画面上にボタンを4個(追加、変更、削除、登録)配置する
DataGridViewの内容に対して処理(追加、変更、削除)をする
この時点では顧客テーブルには反映してはいけない

最後に登録ボタン押下で上記で更新されたデータ全てを顧客テーブルに反映する

顧客テーブル
CD  NAME

このような事を実現したいのですが、やり方が良く分かりません。
よろしくお願いします。

編集 削除
AYAKA  2008-07-14 23:51:23  No: 144942  IP: 192.*.*.*

環境を忘れてました。
WINXP
VS2008PRO
VB.NET
です。
よろしくお願いします。

編集 削除
 2008-07-15 10:38:59  No: 144943  IP: 192.*.*.*

ADO.NETと一言で言っても
データコントロール系を使ってアクセスするのか
それともガチでDataAdapter直接定義して使うのか等によって
答えが変わるかもしれない
どういう形でデータアクセスしてるのか、もうちょっと
詳細を書いた方がいいと思う

なお、その内容によっては私も答えられない可能性も
あるので、ご容赦くだされ

編集 削除
AYAKA  2008-07-15 13:19:20  No: 144944  IP: 192.*.*.*

「あ」さんありがとうがざいます。

「データコントロール系」と「ガチでDataAdapter直接定義」の
違いすらよく分からないのですが...

フォームデザインの下部にデータソース、バインディングソース、
テーブルアダプタが表示されています。

「あ」さんがご存知の方法でかまいません。
よろしくお願いします。

編集 削除
魔界の仮面弁士  2008-07-15 13:47:20  No: 144945  IP: 192.*.*.*

TableAdapter と BindingSource まではあるのですね。
であれば、イメージ的にはこんな感じ。

'------------------------
Private ds As SampleDataSet   '←作成した型付きDataSet名(xsdファイル)

'読みこみ処理
Private Sub Form1_Load(…
  Using ta As New SampleDatasetTableAdapters.顧客TableAdapter()  '←TableAdapter名
    ds = ta.GetData()   '←TableAdapterに追加したデータ取得メソッド
  End Using
  BindingSource1.DataSource = ds   '←DataSet または DataTable を連結させる
End Sub

'書き込み処理
Private Sub Button1_Click(…
  Using ta As New SampleDatasetTableAdapters.顧客TableAdapter()
    ta.Update(ds)   '←DataSetへの削除/追加/更新結果が、これで DB に格納される
  End Using
End Sub
'------------------------


なお、BindingSource を中継させずに、直接、DataGridView に
  DataGridView1.DataSource = ds.顧客
とする事も可能です。

編集 削除
AYAKA  2008-07-15 14:30:51  No: 144946  IP: 192.*.*.*

「魔界の仮面弁士」さんありがとうございます。
早速、作成してみました。

読み込み処理
エラーが表示されてしまいます。
ds = ta.GetData()  ←ここです!

エラー1型 'WindowsApplication1.TestDataSet.顧客DataTable'
 の値を 'WindowsApplication1.TestDataSet' に変換できません。

原因がわかりません。
よろしくお願いします。

編集 削除
AYAKA  2008-07-15 14:52:28  No: 144947  IP: 192.*.*.*

プログラムです。
Public Class Form1
    Private ds As TestDataSet
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Using ta As New TestDataSetTableAdapters.顧客TableAdapter()
            ds = ta.GetData()
        End Using
        顧客BindingSource.DataSource = ds
    End Sub
End Class

編集 削除
 2008-07-15 15:10:27  No: 144948  IP: 192.*.*.*

TableAdapterとかは使った事は無いけど…
エラーの内容を見る感じ、
ds = ta.GetData()
の左辺がDataSetで、右辺がDataTableとなり、
種類が違うし、変換とかが出来る組み合わせでもない、って事っぽい
あと、VS2005ヘルプの「TableAdapterの概要」を見ると
GetDataメソッドはDataTableを返すらしい
…となると、
Private ds As SampleDataSet のかわりに
Private dt as TestDataSet.顧客DataTable にして
各処理の ds を dt に替えればいけるような気がする

編集 削除
AYAKA  2008-07-15 16:02:36  No: 144949  IP: 192.*.*.*

「あ」さんありがとうございます。
DataGridView上で操作(追加、更新、削除)すると更新できました!

プログラムでデータを操作したいのですが
追加
TestDataSet.顧客.Add顧客Row(99, "テスト")
DataGridViewに表示されません。
DataGridView.updateをしても画面更新されません。
リアルに表示させるにはどうしたらいいのでしょうか?

編集 削除
 2008-07-15 16:32:01  No: 144950  IP: 192.*.*.*

DataGridViewにデータをバインドするということは、
基本的にデータ編集をDataGridViewに任せると考えて
いいような気がするので、本来ならDataTableに足すんじゃなくて
DataGridViewに行を足す方がいいんじゃないだろうか
または、DataTableに追加してから
顧客BindingSource.DataSource = Nothing
顧客BindingSource.DataSource = dt
…とすると反映されるかもしれないけど…ちょっと自信ない
(私はデータバインドすれば済むような単純なFormは作ったこと無いんで…)

編集 削除
AYAKA  2008-07-15 17:13:36  No: 144951  IP: 192.*.*.*

「あ」さんありがとうございます。

画面にデータ(Textbox)を入力する
入力されたデータを「追加」ボタン押下で
DataGridViewに追加する。
「登録」ボタンでデータベースに反映する。
DataGridViewは表示のみなんですよ。

>DataGridViewに行を足す方がいいんじゃないだろうか
DataGridViewに行を足す方法はどのような方法でしょうか?

削除は下記の方法でできました。
顧客DataGridView.Rows.Remove(row)

よろしくお願いします。

編集 削除
魔界の仮面弁士  2008-07-15 19:36:52  No: 144952  IP: 192.*.*.*

>>>> ds = ta.GetData()
>>> エラー1型 'WindowsApplication1.TestDataSet.顧客DataTable'
>>>  の値を 'WindowsApplication1.TestDataSet' に変換できません。

あぁっと、失礼。
DataSource に DataSet を指定する場合は、
> ds = ta.GetData()
ではなく、
  ta.Fill(ds.顧客)
にして下さい。


> TestDataSet.顧客.Add顧客Row(99, "テスト")
> DataGridViewに表示されません。
DataSource に指定してあるのが
  Dim ds As New TestDataSet()
  Using ta As TestDatasetTableAdapters.顧客TableAdapter()
    ta.Fill(ds.顧客)
  End Using
  BindingSource1.DataSource = ds
のようになっているであれば、
  ds.顧客.Add顧客Row(99, "テスト")
となるでしょうし、DataSource に指定してあるのが
  Dim tbl As TestDataSet.顧客DataTable
  Using ta As TestDatasetTableAdapters.顧客TableAdapter()
    tbl = ta.GetData()
  End Using
  BindingSource1.DataSource = tbl
となっているのであれば、
  tbl.Add顧客Row(99, "テスト")
と書かねばならないでしょうね。

> DataGridViewは表示のみなんですよ。
BindingSource を使っているのですよね。
入力部(TextBox)等は、バインドしていますか? していませんか?

バインドしていないのであれば、
  Dim row As TestDataSet.顧客Row = TestDataSet.DUAL.NewDUALRow()
  row.CD = CInt(TextBox1.Text)
  row.NAME = TextBox2.Text
  ds.顧客.Add顧客Row(row)
のように書けますし、BindingSource を使っているなら、
  BindingSource1.AddNew()
  TextBox1.Text = "999"  '←これはユーザが手入力しても良し
  TextBox2.Text = "テスト"
  BindingSource1.EndEdit()
のようになるかと。

編集 削除
AYAKA  2008-07-16 00:13:52  No: 144953  IP: 192.*.*.*

「魔界の仮面弁士」さんありがとうございます。

詳しく説明してくださって大変よくわかりました。
ありがとうございました。
修正、削除に挑戦してみます!

編集 削除
魔界の仮面弁士  2008-07-16 01:00:36  No: 144954  IP: 192.*.*.*

# また間違えてしまった…。

> Dim row As TestDataSet.顧客Row = TestDataSet.DUAL.NewDUALRow()

Dim row As TestDataSet.顧客Row = TestDataSet.顧客.New顧客Row()

と読み替えてください。

編集 削除
AYAKA  2008-07-16 15:01:16  No: 144955  IP: 192.*.*.*

「魔界の仮面弁士」さん
お世話になります。

もうひとつ教えてください。

「LEFT OUTER JOIN」をしているSQLの結果を
DataGridviewに表示しています。

ta.Update(ds)<----これがない!

SELECT CD,NAME,ITEM
FROM
顧客 LEFT OUTER JOIN
性別  ON  顧客.CD  =  性別.CD

DataGridview
1 AAA 男
2 BBB 女

顧客テーブル
CD  NAME  S_CD
1  AAA  1
2  BBB  2
性別テーブル
CD  ITEM
1  男
2  女

「LEFT OUTER JOIN」をしているテーブルの
まとめて更新はできないのでしょうか?

よろしくお願いします。

編集 削除
魔界の仮面弁士  2008-07-16 18:45:09  No: 144956  IP: 192.*.*.*

> ta.Update(ds)<----これがない!
恐らくは、TableAdapter の UpdateCommand プロパティが空なのでしょう。
デザイン時に、適切な SQL を設定しておいてください。


LEFT OUTER JOIN である以上、更新先は通常、単一の左側テーブルだけですよね。
なのでこの場合、顧客テーブルに対する UPDATE 文を登録しておけば OK です。


の、UpdateCommand プロパティの指定方法が分からなければ、
「SELECT * FROM 顧客」な DataTable を一時的に登録してみて、
その TableAdapter の UpdateCommand を真似てみると良いでしょう。


> SELECT CD,NAME,ITEM
これだと、CD 列の名前解決でエラーになりませんか?
どちらのテーブルの物なのか不明瞭なので。


> 顧客.CD  =  性別.CD
性別.CD というと、せいぜい、男性/女性/null の 3 状態しか思い浮かばないのですが
それが本当に、顧客.CD と結び付くのでしょうか? (顧客.性別CD とかではなく?)

編集 削除
AYAKA  2008-07-17 09:58:54  No: 144957  IP: 192.*.*.*

「魔界の仮面弁士」さん
お世話になります。

TableAdapter の UpdateCommand プロパティが空の場合こうなるのですね!
ウィザードで
「更新を直接データベースに送信するためのメソッドを作成する」が
選択できない状態になっていたので悩んでました。

こういう場合は自分でUpdateCommandを作成するんですね。

>「SELECT * FROM 顧客」な DataTable を一時的に登録してみて、
>その TableAdapter の UpdateCommand を真似てみると良いでしょう。
中身を確認しましたが結構複雑なんですね!

がんばって挑戦してみます。

ありがとうございました。
また、よろしくお願いします。

編集 削除