0

私はこのシナリオに苦労しており、誰かが私がステップ/ロジックを見逃している場所を明確にするのを手伝ってくれることを願っています。オンラインで検索してみましたが、この問題に対処する例が見つかりませんでした。

最初にロードしたときに一連のオプション(テキストボックス、チェックボックスなど)が表示される検索ページを設定しています。ユーザーはフォームに記入し、フォームを自分自身に送信します。ポストバックされると、ページはユーザーのオプションを使用してデータベースに対してSQLクエリ(たとえば、SELECT ID FROM Customers WHERE Company ='Acme' AND AmtDue = 3)を作成して実行し、結果が表示されます。この部分は問題なく動作します。

故障するのは、ページ付けを追加しようとしているときです。結果セットは、RepeaterにバインドされたDataTableです。PagedDataSourceを使用してページ付けを追加しています。ページ付けは最初のページではうまく機能しますが、後続のページでは機能しません。基本的に、要求された結果の次のページを返す代わりに(たとえば、SELECT ID FROM Customers WHERE Company ='Acme' AND AmtDue = 3)、返される結果は、ユーザーの検索オプションを追加する前のSQLクエリです(たとえば、SELECT ID FROM顧客)。

私の基本的な問題は、通常のPage.IsPostBackと結果のページ付けを区別する方法がわからないことだと思います。これが問題を引き起こしている理由は、フォームデータの再収集、クエリの再構築、およびDBの再クエリを行いたくないためです。

私がオンラインで見つけた例には、ページが読み込まれるたびに再構築されるDataTableのページ付けが含まれていました(たとえば、Page.IsPostBackではありません)。

コードの大まかな概要は次のとおりです。

Public dtCustomers As DataTable = New DataTable()
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
    ' When the page first loads, show the search form with search options.
    If Not Page.IsPostBack Then
        ShowSearchForm()
    ' Once the form is submitted, show the search results.
    Else
        ' ----------------------------------------
        ' This is the part that I'm having trouble with. How do I skip the following two steps (GatherFormData() and BuildDT()) when the user requests a subsequent page?
        GatherFormData()
        dtCustomers = BuildDT()
        ' ----------------------------------------
        BindData()
    End If
End Sub
Sub BindData()
    Dim objPDS As PagedDataSource = New PagedDataSource()
    objPDS.DataSource = dtCustomers.DefaultView
    objPDS.AllowPaging = True
    objPDS.PageSize = intNumPerPage
    objPDS.CurrentPageIndex = Me.ViewState("_CurrentPage")
    rptSearchResults.DataSource = objPDS
End Sub
' Subroutine called when the previous page button is pressed.
Sub GoToPrevPage()
    ' Set viewstate variable to the previous page.
    Me.ViewState("_CurrentPage") -= 1
    BindData()
End Sub
' Subroutine called when the next page button is pressed.
Sub GoToNextPage()
    ' Set viewstate variable to the next page.
    Me.ViewState("_CurrentPage") += 1
    BindData()
End Sub

注:DataTableをキャッシュまたはセッション変数に配置する必要があることは理解していますが、最適な方法を決定していません。

コードの概要をお許しください。ただし、実際のコードは膨大であるため、問題の核心にたどり着くのが簡単になります。

不明な点があれば教えてください。前もって感謝します!

4

1 に答える 1

0

私はあなたがセッション/キャッシュにデータを保存しようとしていると仮定しています(私は後者を好みますが、セッションに保存するユースケースがあります)-ビューステートにキーを保存でき、キーの存在は可能性がありますポストバックがページネーション用かどうかを判断するために使用します。例えば、

if (ViewState["dataKey"] == null)
{
   // first form submittal, do the search
   GatherFormData();
   dtCustomers = BuildDT();
   // store it in cache
   ViewState["dataKey"] = Guid.NewGuid().ToString();  // create a key
   Cache.[ViewState["dataKey"].ToString()] = dtCustomers;  // TODO use Add method to control expiration etc
}

検索がリセットされたとき (または同様の条件) にビューステートをクリアすることが重要です。

最後に、データベース/データ ストアからページングを実行することもできます (たとえば、SQL Server のランキング関数を使用)。これにより、検索結果をセッション/キャッシュに格納する必要がなくなり、データベース トリップを実行する必要がなくなります。各ポストバック。このようなアプローチは、完全な結果セットのサイズが巨大になる可能性がある場合に役立ちます。

于 2013-01-15T09:52:37.840 に答える