在 vb.net 中加载大型数据集

问题描述 投票:0回答:1

我有一个网格视图,它链接到数据库表。数据库表中共有 2,050 条记录。我想每页显示 25 条记录。

以下是重要变量的输出:

  • 2050 条总记录(表中的总记录)
  • 26页大小(一页有26条记录)
  • pageIndex(当前选择的页码)
  • 79 总页数 = (Math.Ceiling(总记录数 / 页大小)

问题: Gridview

GridView1_PageIndexChanging
仅显示 2 页。根据变量 aboce,这是不正确的 bc,我们知道总共应该是 79 页。

问题原因:

<asp:GridView ... PageSize="25">
gridview 每页显示 25 条记录。比在后端我设置了全局变量
Dim pageSize As Integer = 26
(用于测试 i inc 25 到 26)。 Sql 查询正在从数据库加载 26 条记录并放入 Gridview。第一页有 25 条记录,第二页有 1 条记录。等于 26 条记录

*** note如果我更改为

Dim pageSize As Integer = 25
,则在gridview上分页将为0,因为gridview分页似乎基于sql查询第一个结果而不是表中的总计数。

我想要什么:我想显示全部79页。不只是 2 页。

代码:

前端:我有一个页面大小= 25 的网格视图

<asp:GridView ... PageSize="25" AllowPaging="true" PageSize="25" OnPageIndexChanging="GridView1_PageIndexChanging">

全局变量:

Dim currentPageIndex As Integer = 0  ' Stores the current page index (starts from 0).
Dim pageSize As Integer = 26      ' Defines the number of records per page (set to 26).
Dim sortColumn As String = ""     ' Holds the name of the currently sorted column (initially empty).
Dim sortDirection As SortDirection = sortDirection.Ascending ' Tracks the current sorting direction (ascending by default).

主要方法:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        BindGridData()
    End If
End Sub

Gridview分页功能:

Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
    GridView1.PageIndex = e.NewPageIndex
    BindGridData(pageIndex:=e.NewPageIndex)
End Sub

从数据库加载数据并将其链接到gridview:

Protected Sub BindGridData(Optional ByVal pageIndex As Integer = 0,
                          Optional ByVal sortColumn As String = "",
                          Optional ByVal sortDirection As String = "ASC")
    Dim sqlConn1 As New OdbcConnection(myConnectionString1)
    Try
        sqlConn1.Open()

        Dim queryString As String = "SELECT * FROM MyTable "

        ' Add ORDER BY clause for sorting - Use the correct SortDirection enumeration value for ASC or DESC
        If Not String.IsNullOrEmpty(sortColumn) Then
            queryString &= " ORDER BY " & sortColumn & " " & sortDirection.ToString()
        End If
        ' Add paging logic using LIMIT and OFFSET clauses
        queryString &= " OFFSET " & (pageIndex * pageSize) & " ROWS FETCH NEXT " & pageSize & " ROWS ONLY "

        Dim adapter As OdbcDataAdapter = New OdbcDataAdapter(queryString, sqlConn1)
        Dim dt As DataTable = New DataTable()
        adapter.Fill(dt)
        Dim totalRecords As Integer = GetTotalRecordCount() ' total records count from database

        ' Bind data to GridView
        If totalRecords > 0 Then
            GridView1.DataSource = dt
            GridView1.DataBind()

            CountL.Text = dt.Rows.Count & " Records " & totalRecords & " =GetTotalRecordCount() " & (pageIndex + 1) & " of " & (Math.Ceiling(totalRecords / pageSize)) & " Pages"
        Else
            CountL.Text = "No records found."
        End If

        sqlConn1.Close()
    Catch ex As Exception
        ' Handle exception
    End Try
End Sub

获取TotalRecordCount方法:

Private Function GetTotalRecordCount() As Integer
        Dim sqlConn2 As New OdbcConnection(myConnectionString1)
        Try
            sqlConn2.Open()

            Dim countQuery As String = "SELECT COUNT(*) FROM MyTable "
            Dim cmd As OdbcCommand = New OdbcCommand(countQuery, sqlConn2)
            Dim totalRecords As Integer = CInt(cmd.ExecuteScalar())

            Return totalRecords
        Finally
            sqlConn2.Close()
        End Try
    End Function
asp.net vb.net gridview
1个回答
0
投票

好吧,如果您真的想要一个有 78 个值的寻呼机,我们还没有解决?

我想这是可能的,但我从来没有见过这样一个有这么多选择的寻呼机。

如前所述,在您发布的代码中,您会得到一个 RowCount,但永远不要将该 RowCount 提供给寻呼机。并且内置的数据分页器没有该选项。如前所述,内置数据分页器适用于完整数据集。

如前所述,我使用计算机已有 30 年,从未见过具有 78 个选项的数据寻呼机!

但是,这肯定是可能的,这意味着我们必须推出自己的寻呼机。

因此,我们需要一个可以有 1 到“N”种选择的控件。最好的选择是 RadioButton 列表。

所以,我的网格行非常大,所以我每页 12 行。

每行 12 个按钮,对于 2000 行的数据库,大约有 2000/12 = 166 个按钮。然而,79还是160?太多了!!!

所以,说出这个标记:

        <div style="width: 50%">
            <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
                DataKeyNames="ID" CssClass="table table-hover">
                <Columns>
                    <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
                    <asp:BoundField DataField="LastName" HeaderText="LastName" />
                    <asp:BoundField DataField="City" HeaderText="City" />
                    <asp:BoundField DataField="HotelName" HeaderText="Hotel" />
                    <asp:BoundField DataField="Description" HeaderText="Description" />
                    <asp:TemplateField HeaderText="Edit"
                        ItemStyle-HorizontalAlign="Center" ItemStyle-Width="130px">
                        <ItemTemplate>
                            <asp:Button ID="cmdEdit" runat="server" Text="Select"
                                OnClick="cmdEdit_Click" />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>

        <br />

        <div style="width: 100%">

            <asp:RadioButtonList ID="RadioPager" runat="server"
                AppendDataBoundItems="True"
                RepeatDirection="Horizontal"
                DataTextField="Value"
                DataValueField="Key" CssClass="rMyChoice"
                AutoPostBack="true"
                OnSelectedIndexChanged="RadioPager_SelectedIndexChanged"
                RepeatColumns="30">
            </asp:RadioButtonList>

        </div>
    </div>

我们的代码来加载和管理分页?

嗯,使用 RadioButton 列表的一个很好的功能是它会“记住”当前按钮,这将成为我们当前的页面设置。

因此这段代码:

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

    If Not IsPostBack Then
        FirstDataLoad()
        ViewState("NumPages") = NumPages
    Else
        NumPages = ViewState("NumPages")
    End If

End Sub

Sub FirstDataLoad()

    Dim NumPages As Integer = 0
    Dim NumPagesD As Decimal = GetRowCount() / PageSize

    NumPages = Int(NumPagesD)        ' decimal to integer
    If NumPagesD > NumPages Then
        NumPages += 1  ' add 1 if some rows on last page
    End If

    Dim butListSource As New Dictionary(Of Integer, Integer)
    For i = 1 To NumPages
        butListSource.Add(i, i)   'value and display are same (but do NOT have to be!)
    Next

    RadioPager.DataSource = butListSource
    RadioPager.DataBind()
    RadioPager.SelectedIndex = 0    ' list is zero based, but we use PageIndex starting at 1


    Dim strSQL As String =
        "SELECT * FROM tblHotels2 ORDER BY ID"

    GVHotels.DataSource = GetData(strSQL)
    GVHotels.DataBind()


End Sub

Public Function GetRowCount() As Integer

    Dim strSQL = "SELECT COUNT(*) FROM tblHotels2"
    GetRowCount = MyRst(strSQL).Rows(0)(0)


End Function

Public Function GetData(strSQL As String) As DataTable

    ' assume that RadioButon index (zero based page number 
    ' is ALWAYS set BEFORE calling this routine

    Dim PageNumber = RadioPager.SelectedIndex + 1

    Dim strSQL2 As String = strSQL &
        " OFFSET ((@PageNumber - 1) * @RowsPerPage) ROWS
        FETCH NEXT @RowsPerPage ROWS ONLY;"

    Dim cmdSQL As New SqlCommand(strSQL2)
    cmdSQL.Parameters.Add("@PageNumber", SqlDbType.Int).Value = PageNumber
    cmdSQL.Parameters.Add("@RowsPerPage", SqlDbType.Int).Value = PageSize

    Return MyRstP(cmdSQL)


End Function

所以,代码不是很多,但更重要的是代码是否可读。

单选按钮“索引已更改”的工作方式非常类似于组合框,代码是这样的:

Protected Sub RadioPager_SelectedIndexChanged(sender As Object, e As EventArgs)

    Dim strSQL As String =
        "SELECT * FROM tblHotels2 ORDER BY ID"

    GVHotels.DataSource = GetData(strSQL)
    GVHotels.DataBind()


End Sub

请非常仔细地注意我们如何保留页数。请记住,全局表单值在回发之间不会持续存在(它们超出范围)。回发后,服务器不会在内存中保留代码的副本。毕竟,用户可能会合上笔记本电脑的盖子,或者现在可能正在亚马逊上购物。

因此,基于网络的软件就是我们所说的“无状态”。页面、代码变量在每次新回发时都从头开始。这就是网站的工作原理。

我运行上面页面的结果是这样的:

© www.soinside.com 2019 - 2024. All rights reserved.