当我在asp gridview中进行分页时,为什么我的数据集会缩短?

时间:2017-11-14 15:09:26

标签: c# asp.net gridview

标准网格视图:

<asp:GridView runat="server" ID="gvAlerts" AutoGenerateColumns="false"
    DataKeyNames="Id" CssClass="table table-striped table-bordered table-hover"
    OnRowDataBound="gvAlerts_RowDataBound"
    OnSelectedIndexChanging="gvAlerts_SelectedIndexChanging"
    OnRowDeleting="gvAlerts_RowDeleting"
    EmptyDataText="There are no alerts to manage."
    PageSize="10" AllowPaging="true"
    PagerSettings-Position="TopAndBottom"
    PagerSettings-Visible="true"
    PagerSettings-Mode="NumericFirstLast"
    OnPageIndexChanging="gvAlerts_PageIndexChanging">
    <Columns>
        <asp:BoundField HeaderText="" DataField="ContractEntity"
            SortExpression="Supplier" />
        <asp:BoundField HeaderText="Reference" DataField="Reference"
            SortExpression="Reference" />
        <asp:BoundField HeaderText="Date" DataField="Date"
            SortExpression="Date" DataFormatString="{0:dd/MM/yyyy}" />
        <asp:BoundField HeaderText="Contact Person" DataField="Username"
            SortExpression="Username" />
        <asp:BoundField HeaderText="End Date" DataField="EndDate"
            SortExpression="EndDate" DataFormatString="{0:dd/MM/yyyy}" />
        <asp:BoundField HeaderText="Value" DataField="Value"
            SortExpression="Value" DataFormatString="R{0:# ### ###.00}" />
        <asp:BoundField HeaderText="Category" DataField="ContractCategory"
            SortExpression="Category" />
        <asp:CommandField ShowSelectButton="true" SelectText="<i class='glyphicon glyphicon-pencil'></i>" />
        <asp:CommandField ShowDeleteButton="true" DeleteText="<i class='glyphicon glyphicon-trash'></i>" />
    </Columns>
</asp:GridView>

我似乎无法让分页工作正常。

在下面的代码中,我将数据限制为80条记录(用于测试目的)。当我访问不同的页面时,数据确实会实际翻页,但并非所有内容都是如此;每次返回的数据总是少,直到最终分页不再可能,因为没有足够的记录绑定到gridview。

private List<Alert> _alerts { get; set; }

protected void gvAlerts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gvAlerts.PageIndex = e.NewPageIndex;

    try
    {
        PageData(e.NewPageIndex);
    }
    catch (ArgumentNullException ane)
    {
        // Get all Alerts data again since the collection was apparently
        // emptied on postback.
        _alerts = GetAlerts();
        PageData(e.NewPageIndex);
    }
}

private void PageData(int pageIndex)
{
    List<Alert> alerts = _alerts;
    if (pageIndex >= 2)
    {
        alerts = _alerts.Skip(pageIndex * gvAlerts.PageSize).Take(gvAlerts.PageSize).ToList();
    }

    gvAlerts.DataSource = BuildGridViewModel(alerts);
    gvAlerts.DataBind();
}

private List<AlertListViewModel> BuildGridViewModel(List<Alert> alerts)
{
    var model = new List<AlertListViewModel>();
    var u = HttpContext.Current.User.Identity;

    using (var db = new ApplicationDbContext())
    {
        foreach (Alert alert in alerts)
        {
            // Due to poor database design, these queries are unavoidable.
            var contract = db.Contracts.FirstOrDefault(x => x.Id == alert.ContractId);
            var category = db.Categories.FirstOrDefault(x => x.Id == contract.CategoryId).Name;
            var entity = db.ContractEntities.FirstOrDefault(x => x.Id == contract.ContractEntityId).Name;

            model.Add(new AlertListViewModel
            {
                // Map model properties.
            });
        }
    }
    return model;
}

我了解.Skip().Take()可能是缩短数据集的原因但没有这些,我如何更改gridview当前可见的数据?

我在这里遗漏了一些东西。它是什么?如何在不丢失任何数据的情况下获得此gridview分页?

1 个答案:

答案 0 :(得分:1)

GridVIew的缺点是每次都会检索所有记录和/或所有记录都存储在ViewState中。所以如果你想使用Linq创建自己的分页方法。下面是一个如何做到这一点的快速示例。 如果您仍想使用内置分页,请按照InitLipton

的注释进行操作
List<Book> books;
int pageSize = 10;

protected void Page_Load(object sender, EventArgs e)
{
    //fill the collection
    books = fillBooks();

    //create the dynamic pager buttons, this needs to be done on every page load
    createPager();

    //bind the grid for the first time without postback
    if (!IsPostBack)
    {
        bindGrid(0);
    }
}


private void bindGrid(int offSet)
{
    //bind the right amount of items to the grid
    GridView1.DataSource = books.Skip(offSet).Take(pageSize).ToList();
    GridView1.DataBind();
}


private void createPager()
{
    //loop for every x items in the collection
    for (int i = 0; i < (books.Count / pageSize); i++)
    {
        //create a linkbutton
        LinkButton lb = new LinkButton();

        //add the properties
        lb.Text = (i + 1).ToString();
        lb.CommandArgument = i.ToString();

        //bind the command method
        lb.Command += Lb_Command;

        //add the linkbutton to the page
        PlaceHolder1.Controls.Add(lb);

        //add some spacing
        PlaceHolder1.Controls.Add(new Literal() { Text = "&nbsp;" });
    }
}


private void Lb_Command(object sender, CommandEventArgs e)
{
    //rebind the grid with the next 10 items
    bindGrid(Convert.ToInt32(e.CommandArgument) * 10);
}

和aspx

<asp:GridView ID="GridView1" runat="server" EnableViewState="false"></asp:GridView>
<br />
<br />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>