none
DataGridのページ切替時に別の人の検索結果が表示されてしまう RRS feed

  • 質問

  • お世話になります。

    VisualStudio2003 C# Webフォームでシステムを開発しております。
    検索結果が非常に多くなるようなページなので、ページング機能を追加しました。
    ところが、複数ユーザで実行した場合に別の人の検索結果が表示されてしまいます。
    -----------------------------------------------------------
    ①Aさんが検索
    ②Bさんが検索
    ③Aさんがページ移動  →ここで②の検索結果が返されてしまう。
    -----------------------------------------------------------
    データセットの定義でstaticにしているのがマズイのではないかと思い、
    staticを外して実行してみたのですが、そうすると、ページ移動時に
    「IListSource に、データ ソースがありません。 」というエラーが表示されてしまいました。

    ◆ソース◆
    //データセットの定義
    private static DataSet dsTEST = new DataSet();
    //検索処理
    private void btn_Search_Click(object sender, System.EventArgs e)
    {
     dsTEST.Tables.Clear();
     using (OracleCommand cmd = new OracleCommand())
     {
      cmd.Connection = cnn;
      //データ検索
      cmd.CommandText = "--(SQLセット)--";
      cmd.BindByName = true;
      cmd.Parameters.Add("code","--(条件)--");
      //SQL実行
      adp1.SelectCommand = cmd;
      adp1.Fill(dsTEST,"TABLE1");
     }
     DataGrid1.DataSource = dsTEST;
     DataGrid1.DataBind();
    }
    //ページ移動
    private void DataGrid1_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
    {
     if(DataGrid1.PageCount > 0)
     {
      DataGrid1.CurrentPageIndex = e.NewPageIndex;
      DataGrid1.DataSource = dsTEST;
      DataBind();
     }
    }
    ◆◆◆

    オブジェクト指向についてまだまだ勉強不足で、どのように修正して良いのかがわかりません。
    大変恐縮ですが、もし何か分かる方がいらっしゃいましたら教えて頂けないでしょうか?

    宜しくお願い致します。

    2007年8月31日 4:39

すべての返信

  • staticにすると全ユーザーに共有されてしまいますので、お察しの通りstaticはまずいです。

     

    ではどうするかといいますと、最初にDataSetを作成したら、それをsession変数などに入れて持ちまわる必要があります。

    次のページの切り替え時には、session変数からそのDataSetを取り出して利用します。

    2007年8月31日 5:14
    モデレータ
  • trapemiya様

     

    ありがとうございます!
    Session変数を利用するように変更したところ正常に動作しました。
    急いで修正しなければならなかったので、とても助かりました。

    そこで引続き質問をさせて頂きたいのですが
    Session変数を利用するようにするとやはりサーバに負荷が掛かるのですよね?
    1度に格納するデータ量が数千件~1万件程度になるため、
    同時に使用する人数が増えると厳しいのではないかと思ったのですが。
    データが多い場合、皆さんはどのように対処されているのでしょう?

    2007年8月31日 6:46
  • ページングに関して取得するデータ量が多い場合、例えば検索結果が100ページになった場合を考えて見ましょう。この場合、表示しているのは1ページですが、100ページ分のデータを取得していることになります。表示している1ページ以外の99ページ分は表示されないわけですから、取得する意味がなく、全くの無駄になります。

    そのような場合にはカスタムページングを利用します。

     

    HOW TO:良好なパフォーマンスのクエリ結果を介してページ
    http://support.microsoft.com/kb/318131/ja

     

    デベロッパー・バックナンバー
    SQL Server 2000で大量の結果セットを効率的にページングする方法
    http://japan.internet.com/developer/20060530/25.html

     

    [ASP.NET]DataGridコントロールで大量のデータをページ表示するには?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/073custompg/custompg.html

     

    その他、カスタムページングで検索すれば、いくつか例が探せると思います。

    また、単に検索結果を表示するだけでしたら、DataSetではなくDataReaderが使えます。
    2007年8月31日 7:13
    モデレータ
  • trapemiy 様

    度々ありがとうございます。

    カスタムページングを使用するよう作り変えたいと思います。

     

    あと一つ、大変初歩的な質問なのですが、
    DataSetを使用してWebでの一括更新(検索した複数のデータを纏めて更新)するような場合、
    Session変数を使用せずにDataSetの内容を保持するような事は有り得ないのでしょうか?
    だとすると、私はものすごい勘違いをしていたようです…。

    2007年9月3日 6:49
  • プログラムで生成したインスタンスは、次のポストバック時には消えてしまいます。(今回の場合はDataSetというインスタンスです) したがって、次のポストバック時にふたたびそれを使えるようにどこかにしまっておく必要があります。これは一般的にはSession変数ですが、ViewStateでもできないことはありません。しかし、ViewStateの場合ですとクライアント(ブラウザ)に大量のコードが送られるので現実的ではないでしょう。

    Webアプリケーションの場合はWindowsアプリケーションと違い、基本的に一つの操作毎にポストバックが発生するため、完全にサーバーと切り離されて動作するわけではありません。したがって、Windowsアプリケーションのようにサーバーから切り離されたデータテーブル上でまとめて作業を行っておき、一度にそれらをデータベースサーバーへ書き戻すようなことをしても、あまり意味がないように思えます。

    2007年9月3日 8:22
    モデレータ