Razor Pages 中的分页和过滤组合

pagination & filtering combo in Razor Pages

有一个问题困扰了我 2 天。想不通,所以也许另一双或几双新鲜的眼睛可以为我指明正确的方向。

我有一个用于 CRUD 操作的存储库

    public async Task<int> GetCount()
    {
        var data = await GetData();
        return data.Count;
    }

    public async Task<List<Item>> GetPaginatedResult(int currentPage, int pageSize = 20)
    {
        var data = await GetData();
        return data.OrderBy(d => d.Day).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
    }

    public async Task<List<Item>> GetData()
    {
        return await _db.Set<Item>().ToListAsync();
    }

项目是一个简单的模型class,我在这里没有问题。 在我尝试将分页与过滤相结合之前,分页效果很好。

我有一个提供年份(2022、2021)的下拉菜单和另一个提供月份(整数值)的下拉菜单。

这是导致问题的部分代码:

        var tempData = await repository!.GetPaginatedResult(CurrentPage, PageSize);
        Items = tempData;
        //Items = tempData.Where(s => s.Year == SearchYear && s.Month == Month);
        var sumList = await repository!.GetData();
        //Count = sumList.Where(s => s.Year == SearchYear && s.Month == Month).OrderBy(x => x.Day).Count();
        Count = sumList.OrderBy(x => x.Day).Count();
        //SumValues = sumList.Where(s => s.Year == SearchYear && s.Month == Month).OrderBy(x => x.Day).Sum(s => s.Value);
        SumValues = sumList.Sum(s => s.Value);

这种分页方式在应用过滤之前起作用。

当我改用这一行时:

Items = tempData.Where(s => s.Year == SearchYear && s.Month == Month);

没有错误,但有奇怪的行为。例如,当使用注释行而不是当前行时,我在第一页上只显示了 9 条记录而不是 20 条记录,PageSize 是什么,同样在第一次单击 Next 分页按钮之后,如 Items 列表为空。

SumValues,显示筛选记录总和的文本工作正常,其他一切都是一团糟。

视图是 classic 用于填充 table:

     <tbody>
        @foreach(var obj in Model.Items!)
        {
            <tr>
                <td>@obj.Day</td>
                <td>@obj.Month</td>
                <td>@obj.Year</td>
                <td>@obj.ItemName</td>
                <td>@obj.Destination</td>
                <td class = "text-end">@string.Format("{0:#,#}", obj.Quantity)</td>
                <td class = "text-end">@string.Format("{0:#,#.00}", obj.Value)</td>
                <td class = "text-center">Edit Delete</td>
            </tr>
        }
    </tbody>

更新: 我按照建议将操作顺序更改为:

var tempData = await repository!.GetData();
var filteredData = tempData.Where(s => s.Year == SearchYear && s.Month == Month);
Items = await repository!.GetPaginatedResult(filteredData, CurrentPage, PageSize);
Count = filteredData.Count();
SumValues = filteredData.Sum(s => s.Value);

现在,当我在搜索组合框中更改选定的年份和月份时,它显示正常,有 20 条记录。但是当我点击第二页的下一步按钮时出现了问题,table 是空的。根据 Visual Studio 中的调试信息,tempData 具有应有的记录数,但 filteredData 变为空。不知道为什么。 :/

link 上的字符串用于悬停时的下一步按钮说 .../Year=2021&Month=12&CurrentPage=2 就像它应该

我将存储库中的方法更改为:

public Task<List<Item>> GetPaginatedResult(IEnumerable<Item> tempList, int currentPage, int pageSize = 20)
    {
        return Task.FromResult(tempList.OrderBy(d => d.Day).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList());
    }

有关页面 links 的视图代码:

            <ul class="pagination">
                @if (Model.ShowPrevious)
                {
                    <li class="page-item text-center">
                        <a asp-page="/Poetracker/Index" 
                            asp-route-SearchTerm = "@Model.SearchYear"
                            asp-route-Month = "@Model.Month"
                            asp-route-CurrentPage="@(Model.CurrentPage - 1)"  
                            class="btn btn-outline-primary btn-sm"  style = "width:100px"><i class="fas fa-backward"></i>&nbsp;Previous</a>
                            &nbsp;
                    </li>
                }
                @if (Model.ShowNext)
                {
                    <li class="page-item text-center">
                        <a asp-page="/Poetracker/Index" 
                            asp-route-SearchTerm = "@Model.SearchYear"
                            asp-route-Month = "@Model.Month"
                            asp-route-CurrentPage="@(Model.CurrentPage + 1)" 
                            class="btn btn-outline-primary btn-sm"  style = "width:100px"><i class="fas fa-forward"></i>&nbsp;Next</a>
                    </li>
                }
            </ul>

最终编辑:当我将 属性 名称从 SearchTerm 更改为 SearchYear 时忘记相应地更新 asp-route。现在按预期工作。

同时处理过滤和分页时,需要注意操作顺序。只有过滤后,您才会知道无论如何要显示多少条记录。好像是先分页再过滤,所以f.e。在第一页,20 条记录中有 9 条符合您的条件,在第二页,N 条记录中有 0 条符合您的条件。我建议颠倒操作顺序。