none
gridview の更新が出来ない。 RRS feed

  • 質問

  • asp.net (vb.net)の勉強をしていますが、gridview の更新が出来ませんでした。原因は不明です。

    画面が二つあります。

    ①商品一覧表(listGoods)画面

    ②追加(add)画面

    商品一覧表に「新しい商品追加」ボタンがあります。このボタンを押下すると、追加の画面が開きます。追加画面の登録ボタンを押下すると、商品の追加をし、商品一覧表画面に戻ります。その時、商品一覧表のgridviewにレコードの追加されたいですけど出来ませんです。

    商品一覧表は以下です。

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            'Button1.Attributes("OnClick") = "return confirm('テストを実行しますか');"

            If Not IsPostBack Then

                If Session("categoriID") = "" Then
                    Me.TextBox1.Text = 1
                Else
                    TextBox1.Text = Session("categoriID")
                End If
                LoadDropDownList()
                'LoadSQL()
                'myGridBind()
            Else
                'LoadSQL()

            End If
            LoadSQL()
        End Sub


        Public Sub LoadSQL()
            Dim dbcon As OleDbConnection
            Dim dbcmd As OleDbCommand
            Dim dataRead As OleDb.OleDbDataReader

            Dim dt As DataTable
            Dim dr As DataRow

            Dim sqlStr As String
            Dim sqlUrl As String

            '接続文字列
            sqlUrl = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\developmentDB.mdb"

            'DBコネクション作成
            dbcon = New OleDbConnection(sqlUrl)

            'DB接続
            dbcon.Open()

            Dim fs As String = ""
            'Dim sql As String

            'カテゴリー名の条件指定と条件式の作成
            If DropDownList1.SelectedIndex > -1 Then
                If fs <> "" Then
                    fs &= " AND "
                End If
                'fs &= "categories.categoryName = '" & Strings.Left(Me.Label1.Text, 50) & "'"
                fs &= "categories.categoryName = '" & Strings.Left(DropDownList1.SelectedItem.Text, 50) & "'"
                'fs &= "categories.categoryName = 'トイレ'"
            End If
            'SQLステートメントの定義
            sqlStr = "SELECT goods.*, categories.categoryName, makers.makerName FROM ((categories " & _
               "INNER JOIN goods ON categories.categoryID = goods.categoryID) " & _
               "INNER JOIN makers ON goods.makerID = makers.makerID) "

            '条件が指定されているときにはWHERE句を追加する
            If fs <> "" Then
                sqlStr &= " WHERE " & fs
            End If


            'SQLコマンド作成
            dbcmd = New OleDbCommand(sqlStr, dbcon)

            'SQL文実行
            dataRead = dbcmd.ExecuteReader()

            'データテーブル作成
            dt = New DataTable()

            dt.Columns.Add(New DataColumn("goodsID", GetType(String)))
            dt.Columns.Add(New DataColumn("goodsName", GetType(String)))
            dt.Columns.Add(New DataColumn("価格", GetType(String)))
            dt.Columns.Add(New DataColumn("備考", GetType(String)))
            dt.Columns.Add(New DataColumn("メーカー", GetType(String)))


            '結果を読み込み
            Dim bbsStr As String = ""
            While (dataRead.Read())
                dr = dt.NewRow()

                dr(0) = dataRead("goodsID")
                dr(1) = dataRead("goodsName")
                dr(2) = dataRead("Price")
                dr(3) = dataRead("goodsNotes")
                dr(4) = dataRead("makerName")
                dt.Rows.Add(dr)
            End While

            'DataSourceに設置
            Me.GridView2.DataSource = dt.DefaultView
            Me.GridView2.DataBind()
            Me.GridView2.Dispose()


            'DBクローズ処理
            dataRead.Close()
            dbcmd.Dispose()
            dbcon.Close()
            dbcon.Dispose()

        End Sub

    ///////////////////////////////////////////////////////////////

    追加画面は以下

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            If IsPostBack Then
                'Me.TxtKategori.Text = Session("categoriID")
                'Me.TxtMeka.Text = Session("meka")

            Else
                Me.TxtKategori1.Text = Session("categoriID")

                Session.RemoveAll()

                'カテゴリーIDをセッションに入れる。
                'Session("categoriID") = Me.TxtKategori1.Text.ToString
                DropDownList()

            End If

        End Sub

        Protected Sub BtnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BtnAdd.Click
            Try
                syouhin = New goodsCls(Me.TxtSyouhinID.Text, Me.TxtKategori.Text, Me.TxtSyouhinMe.Text, Me.TxtKakaku.Text, Me.TxtNotes.Text, Me.TxtMeka.Text)

                'データベースアクセスオブジェクト生成()
                dbIO = New goodsClsDB(syouhin.syouhinID)

                ' 商品マスターに1レコード追加
                If dbIO.InsertGoods(syouhin) = True Then

                    'MsgBox("商品ID「" & syouhin.syouhinID & "」のレコードが追加されました。")
                    'Response.Write("<script>window.alert('商品ID「" & syouhin.syouhinID & "」のレコードが追加されました。');</script>")
                    'カテゴリーIDをセッションに入れる。
                    Session.Remove("categoriID")
                    Session("categoriID") = Me.TxtKategori.Text.ToString

                    Session.Remove("SyouhinID")
                    Session("SyouhinID") = Me.TxtSyouhinID.Text.ToString

                    Response.Redirect("ListGoods2.aspx")


                Else
                    'MsgBox("商品IDは追加できませんでした")[
                    Response.Write("<script>window.alert('商品IDは追加できませんでした');</script>")
                End If

    追加画面から戻るとき商品一覧表のgridviewは更新されないが、その後IEの最新の情報の更新「F5」を押下するとgridviewに更新されます。たぶんリダイレクトの問題だと思いますが、どこにどうすればいいでしょうか?

    教えてくれば助かります、よろしくお願いします。

    2010年9月14日 5:15

回答

  • やはり明示的にコミットしていませんね。
    Jet エンジンは書き込み&読み込み用にデータをキャッシュしますので、別の Connection ですぐに読み出したい場合には明示的にキャッシュを吐き出してやらないといけません。
    ブレークポイントを置いたときに期待通り動くのは、一旦ブレークすることによって、キャッシュが更新される時間が稼げただけでしょう。

     実装マルチユーザー カスタム カウンターの Jet 4. 0 と ADO 2. 1 にする方法
     http://support.microsoft.com/kb/240317/ja

     Jet Engineのキャッシュとその制御
     http://www.canalian.com/workshop/access/JetCache.html

     PC覚え書き | ブレークポイントのある/なしで結果が変わる【VB】
     http://pinka99.ddo.jp/nanao/work/Jet.html
    • 回答としてマーク sudipbaral 2010年9月15日 7:36
    2010年9月15日 3:18

すべての返信

  • リダイレクトの問題ではなくて、ブラウザーがページをキャッシュしているのではないでしょうか?
    「ASP.NET キャッシュ 無効」と検索すると、たくさんヒットします。

    2010年9月14日 5:48
  • キャッシュを無効にしていました。

    追加画面から戻って商品一覧表の表示するとき、追加された商品を更新されませんが、商品一覧表の他のボタン(又はIEの最新の情報の更新「F5」)を押下するとgridviewに更新をされます。

    原因はまだ不明です。

    よろしくお願いします。

    2010年9月14日 7:03
  • キャッシュが原因でないのであれば、サーバー側のコードをトレース実行するとよいかと。
    asp.net (vb.net)の勉強をしていますが、

    勉強にうってつけだと思います。
    2010年9月14日 7:20
  • 疑って申し訳ありませんが、キャッシュっぽい気がしますので、キャッシュが本当に働いていないか、Page_Load内にブレークポイントを設定して確かめてみられてはいかがでしょうか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年9月14日 7:21
    モデレータ
  • Page_Load内にブレークポイントを設定して実行すると正常に更新されますが、

    ブレークポイントを設定してない時は更新されません。

    2010年9月14日 7:29
  • sudipbaral

    はじめまして。

    vbは詳しくありませんが、まずはシンプルなSELECT文で確認してみてはいかがでしょうか?
    ex)Select * from [Table]


    こちらで作成し確認したところ問題なく更新されました。

    謎ですね。

    SessionとDropDownListがSQLにどう影響するのか、コミットのタイミング等わかりませんでしたので。。。
    質問内容にあったソースを元に自作したところ、問題なく更新されました。

    MCITP(Database Developer/Database Administrator) MCPD(Web Developer/Windows Developer) MCTS(Distributed Applications) http://techbank.jp/Community/blogs/nob/default.aspx
    2010年9月14日 8:36
  • ノブヒデ様

    有難うございます。

    やって見ます。

     

     

    2010年9月14日 8:47
  • Page_Load内にブレークポイントを設定して実行すると正常に更新されますが、

    ブレークポイントを設定してない時は更新されません。


    ブレークポイントの有無よりも、INSERT してから一定時間を経過しないとデータが有効にならないということでしょうか。
    goodsClsDB クラスやら InsertGoods メソッドの中で明示的にコミットをしていないとか、コネクションを開きっぱなしとか、コネクションの Close がファイナライザー任せになっているとか。
    商品一覧表の Page_Load に待ちを入れると動いたりして。
    2010年9月14日 9:48
  • 他のサイトに同じ質問者の方の同じ質問と思われるページがありますの
    で貼っておきます。

    http://ap.atmarkit.co.jp/bbs/core/vblab/24307
    http://ap.atmarkit.co.jp/bbs/core/vblab/24331

    マルチポストはダメとはいいませんが、質問者の方はその旨知らせてい
    ただければと思います。

    2010年9月14日 14:12
  • コメントアウトしたコードが入っていて見にくいし、肝心な部分がなか
    ったりで原因はさっぱり分かりません。

    回答者のみなさんは、ありそうな原因を想定して回答しておられますが、
    このままやり取りを続けても、解決するのはかなり難しそうな気がしま
    す。

    一度、アップされたコードを問題が再現できる必要最小限のコードに絞
    ってみませんか?

    Session の受け渡しがうまくいかず「追加画面」から「一覧表画面」に
    うまく必要なデータが渡ってないとか、WHERE 句の組み立てに問題があ
    るとか、問題のありそうな部分を順に削除していくなどしてみてくださ
    い。

    自分で問題の部分が特定でき、対処できるかもしれません。

    自分で見つけられなくても。必要最小限に絞ったうえで、コードをすべ
    てアップしてもらえれば、回答者のほうでも検証できてお役に立てるか
    もしれません。

    ところで、何故 AccessDataSource を使わないのですか? コードが簡
    略化でき、見やすくなって、間違いも大幅に減ると思います。勉強のた
    め ADO.NET ライブラリを使ってコードを書いているということではな
    いですよね。

    2010年9月14日 14:18
  • >コメントアウトしたコードが入っていて見にくいし、肝心な部分がなか
    >ったりで原因はさっぱり分かりません。
    
    >回答者のみなさんは、ありそうな原因を想定して回答しておられますが、
    >このままやり取りを続けても、解決するのはかなり難しそうな気がしま
    >す。
    
    >一度、アップされたコードを問題が再現できる必要最小限のコードに絞
    >ってみませんか?
    

    すみませんでした。

    シンプルにしましたが、原因は同じ,見つかりません・・・・・・・・・・・・・

    最初の商品一覧表画面はAccessDataSource を使いました為、コードは簡
    略化できました。コードは以下のようです。

        '追加フォーム開くボタン
        Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
            '商品追加フォームを開く
            Response.Redirect("addGoods2.aspx")
        End Sub

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        End Sub

    /////////////

    追加画面のコードは以下のようです。

    Partial Class addGoods2

        Inherits System.Web.UI.Page
        ' データベースアクセスクラス
        Private dbIO As goodsClsDB

        ' 商品データクラス
        Private syouhin As goodsCls

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        End Sub

        '追加ボタン
        Protected Sub BtnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BtnAdd.Click
            Try
                syouhin = New goodsCls(Me.TxtSyouhinID.Text, Me.TxtKategori.Text, Me.TxtSyouhinMe.Text, Me.TxtKakaku.Text, Me.TxtNotes.Text, Me.TxtMeka.Text)

                'データベースアクセスオブジェクト生成()
                dbIO = New goodsClsDB(syouhin.syouhinID)

                ' 商品マスターに1レコード追加
                If dbIO.InsertGoods(syouhin) = True Then
                    Response.Redirect("ListGoods2.aspx")
                Else
                    Response.Write("<script>window.alert('商品IDは追加できませんでした');</script>")
                End If

            Catch ex As TextIDSameException
                ' 商品IDに例外が発生した時の処理
                Session("code") = Me.TxtSyouhinID.Text.ToString
                Session.Remove("categoriID")

                Response.Redirect("addGoodsError2.aspx")

            Catch ex As Exception
                ' 上記以外の例外が発生した時の処理
                Response.Write("<script>window.alert('" & ex.ToString & "');</script>")
            End Try

        End Sub
    End Class


    Public Class goodsClsDB
        '////////// データベースアクセスクラス //////////
        ' 変数
        ' 商品ID
        Private syouhinID As String
        '========================================================
        ' 機能:コンストラクタ
        ' 引数:商品ID
        '========================================================
        Public Sub New(ByVal syouhinID As String)
            MyBase.New()
            Me.syouhinID = syouhinID
        End Sub

        '********************************************************
        ' 機能:商品テーブルに1レコードを追加するメソッド
        ' 引数:goodsClsオブジェクト
        ' 戻値:True  --> 登録成功.  False --> 登録失敗
        '********************************************************
        Public Function InsertGoods _
            (ByVal syouhin As goodsCls) As Boolean
            Dim con As New OleDbConnection()
            Dim cmd As New OleDbCommand()

            ' DB接続文字列の設定
            con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\developmentDB.mdb"
            ' コネクションの設定
            cmd.Connection = con

            ' DB接続を開く
            con.Open()

            ' SQL文の設定
            cmd.CommandText = "INSERT INTO goods "
            cmd.CommandText &= "(goodsID, categoryID, goodsName, price, "
            cmd.CommandText &= "goodsNotes, makerID) "
            cmd.CommandText &= "VALUES(@syouhinID, @kategori, @syouhinMe, @kakaku, "
            cmd.CommandText &= "@notes, @meka)"

            ' パラメータの設定
            cmd.Parameters.Add("@syouhinID", OleDbType.Char, 9)
            cmd.Parameters("@syouhinID").Value = syouhin.syouhinID

            cmd.Parameters.Add("@kategori", OleDbType.Integer)
            cmd.Parameters("@kategori").Value = syouhin.kategori

            cmd.Parameters.Add("@syouhinMe", OleDbType.Char, 40)
            cmd.Parameters("@syouhinMe").Value = syouhin.syouhinMe

            cmd.Parameters.Add("@kakaku", OleDbType.Integer)
            cmd.Parameters("@kakaku").Value = syouhin.kakaku

            cmd.Parameters.Add("@notes", OleDbType.Char, 100)
            cmd.Parameters("@notes").Value = syouhin.notes

            cmd.Parameters.Add("@meka", OleDbType.Integer)
            cmd.Parameters("@meka").Value = syouhin.meka

            ' キー値のレコード存在しなければテーブルに追加
            If Me.ExistGoods() = False Then
                ' 商品テーブル挿入処理実行
                cmd.ExecuteNonQuery()
                ' 正常リターン
                Return True
            Else
                ' エラーリターン
                Return False
            End If
            ' DB接続を閉じる
            con.Close()
        End Function

        '********************************************************
        ' 機能:レコードが商品テーブルに存在するか否かを調べる
        ' 引数:なし
        ' 戻値:True  --> 存在する  False --> 存在しない
        '********************************************************
        Public Function ExistGoods() As Boolean
            Try
                Dim con As New OleDbConnection()
                Dim cmd As New OleDbCommand()

                ' DB接続文字列の設定
                con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|\developmentDB.mdb"

                ' コネクションの設定
                cmd.Connection = con

                ' DB接続を開く
                con.Open()
                ' SQL文の設定
                cmd.CommandText = "SELECT goodsID, goodsName FROM goods ORDER BY goodsID"
                ' SQL文の設定
                cmd.CommandText = "SELECT COUNT(*) FROM goods WHERE goodsID = @syouhinID"

                ' SQL文パラメータの設定
                cmd.Parameters.Add("@syouhinID", OleDbType.Char, 9)
                cmd.Parameters("@syouhinID").Value = Me.syouhinID

                ' 商品テーブルから該当商品IDのレコード数取得
                Dim count As Integer
                count = CInt(cmd.ExecuteScalar())
                If count > 0 Then
                    ' レコードが存在する時の処理
                    Return True
                Else
                    ' レコードが存在しない時の処理
                    Return False
                End If

                ' DB接続を閉じる
                con.Close()

            Catch ex As Exception
                ' 例外が発生した時の処理
                MsgBox(ex.ToString)
            End Try
        End Function
    End Class


    '////////// 商品ID同じときの例外クラス //////////
    Public Class TextIDSameException
        Inherits ApplicationException
        '========================================================
        ' 機能:コンストラクタ
        ' 引数:エラーメッセージ
        '========================================================
        Public Sub New(ByVal errorMessage As String)
            MyBase.New()

        End Sub
    End Class


    'goodsClsクラスの作成 :エラーを確認する
    Public Class goodsCls
        '========================================================
        ' 機能:コンストラクタ
        ' 引数:goods
        '========================================================
        Public Sub New(ByVal syouhinID As String)
            MyBase.New()
            Me.syouhinIDValue = syouhinID
        End Sub

        '========================================================
        ' 機能:コンストラクタ
        ' 引数:商品ID、カテゴリー 商品名、 価格、備考、メーカー
        '========================================================
        Public Sub New(ByVal syouhinID As String, ByVal kategori As String, _
            ByVal syouhinMe As String, ByVal kakaku As String, ByVal notes As String, ByVal meka As String)

            MyBase.New()

            '【商品IDエラーチェック】
            If syouhinID = "" Then
                ' 未入力はエラー
            Else
                ' 商品テーブルアクセスオブジェクト
                Dim dbIO As New goodsClsDB(syouhinID)

                ' 商品マスタにこの商品IDがあればエラー
                If dbIO.ExistGoods() = True Then
                    Throw New TextIDSameException("")
                Else
                    Me.syouhinIDValue = syouhinID
                End If
            End If

            '【カテゴリーのエラーチェック】
            Me.kategori = kategori
            '【商品名のエラーチェック】
            Me.syouhinMe = syouhinMe
            '【価格のエラーチェック】
            Me.kakaku = kakaku
            '【備考のエラーチェック】
            Me.notes = notes
            '【メーカーのエラーチェック】
            Me.meka = meka


        End Sub

        'プロパティ:商品ID
        Private syouhinIDValue As String

        Public ReadOnly Property syouhinID() As String

            ' Getプロパティ
            Get
                Return Me.syouhinIDValue
            End Get

        End Property


        'プロパティ:カテゴリーID
        Private kategoriValue As String

        Public Property kategori() As String

            ' Getプロパティ
            Get
                Return Me.kategoriValue
            End Get
            ' Setプロパティ
            Set(ByVal value As String)
                kategoriValue = value
            End Set

        End Property

        'プロパティ:商品名
        Private syouhinMeValue As String

        Public Property syouhinMe() As String

            ' Getプロパティ
            Get
                Return Me.syouhinMeValue
            End Get

            ' Setプロパティ
            Set(ByVal value As String)
                syouhinMeValue = value
            End Set

        End Property

        'プロパティ:価格
        Private kakakuValue As String

        Public Property kakaku() As String
            ' Getプロパティ
            Get
                Return kakakuValue
            End Get

            ' Setプロパティ
            Set(ByVal value As String)
                kakakuValue = value
            End Set
        End Property


        'プロパティ:備考
        Private notesValue As String

        Public Property notes() As String

            ' Getプロパティ
            Get
                Return Me.notesValue
            End Get

            ' Setプロパティ
            Set(ByVal value As String)
                notesValue = value
            End Set

        End Property

        'プロパティ:メーカー
        Private mekaValue As String

        Public Property meka() As String

            ' Getプロパティ
            Get
                Return Me.mekaValue
            End Get
            ' Setプロパティ
            Set(ByVal value As String)
                mekaValue = value
            End Set
        End Property
    End Class

    /////////////////////////

    コードは以上です。教えてくれれば助かります。よろしくお願いします。

     

     

    2010年9月15日 2:07
  • やはり明示的にコミットしていませんね。
    Jet エンジンは書き込み&読み込み用にデータをキャッシュしますので、別の Connection ですぐに読み出したい場合には明示的にキャッシュを吐き出してやらないといけません。
    ブレークポイントを置いたときに期待通り動くのは、一旦ブレークすることによって、キャッシュが更新される時間が稼げただけでしょう。

     実装マルチユーザー カスタム カウンターの Jet 4. 0 と ADO 2. 1 にする方法
     http://support.microsoft.com/kb/240317/ja

     Jet Engineのキャッシュとその制御
     http://www.canalian.com/workshop/access/JetCache.html

     PC覚え書き | ブレークポイントのある/なしで結果が変わる【VB】
     http://pinka99.ddo.jp/nanao/work/Jet.html
    • 回答としてマーク sudipbaral 2010年9月15日 7:36
    2010年9月15日 3:18
  • みんなさん

    有難うございます。

    totojo様が教えた通りにやったら、正常に更新されました。

    thnak you

     

    2010年9月15日 7:36
  • sudipbaral さん>

    > totojo様が教えた通りにやったら、正常に更新されました。

    ↓ こちらの方にも、原因と解決方法を書いておいてはいかがですか?

    http://ap.atmarkit.co.jp/bbs/core/vblab/24307
    http://ap.atmarkit.co.jp/bbs/core/vblab/24331

    2010年9月15日 14:06