You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改GetAll函数实现ServerNames数据的服务端分页?

服务端分页实现方案(基于.NET Core 7 Blazor + EF Core)

1. 调整服务层方法定义

首先修改GetAll方法的参数与返回类型,接收分页核心参数(页码、页大小),并返回包含分页元数据的结果对象(假设你已定义PagedResult<T>分页模型):

// 分页结果模型(如果未定义可直接使用)
public class PagedResult<T>
{
    public List<T> Items { get; set; } = new();
    public int TotalCount { get; set; }
    public int PageIndex { get; set; }
    public int PageSize { get; set; }
    public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
}

// 定义DTO用于返回关联后的数据(避免直接暴露实体)
public class ServerNameWithTypeDto
{
    public int Id { get; set; }
    public string ServerName { get; set; }
    public string ServerTypeName { get; set; }
    // 按需添加其他字段
}

2. 实现关联查询的服务端分页

修改GetAll方法,基于EF Core的IQueryable实现真正的服务端分页(而非内存分页),结合你的分页扩展类完成逻辑:

public async Task<PagedResult<ServerNameWithTypeDto>> GetAll(int pageIndex, int pageSize)
{
    // 构建关联查询的IQueryable(延迟执行,未触发数据库查询)
    var query = _context.ServerNames
        .Include(s => s.ServerType) // 关联ServerType表
        .Select(s => new ServerNameWithTypeDto
        {
            Id = s.Id,
            ServerName = s.Name,
            ServerTypeName = s.ServerType.TypeName
            // 映射其他需要的字段
        });

    // 调用你的分页扩展类完成分页逻辑
    return await query.PaginateAsync(pageIndex, pageSize);
}

如果你的分页扩展类未封装总条数查询,可手动实现:

public static async Task<PagedResult<T>> PaginateAsync<T>(this IQueryable<T> query, int pageIndex, int pageSize)
{
    var totalCount = await query.CountAsync();
    var items = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
    
    return new PagedResult<T>
    {
        Items = items,
        TotalCount = totalCount,
        PageIndex = pageIndex,
        PageSize = pageSize
    };
}

3. 分页参数校验(可选但推荐)

在方法内添加参数合法性校验,避免无效请求:

public async Task<PagedResult<ServerNameWithTypeDto>> GetAll(int pageIndex, int pageSize)
{
    // 参数校验
    pageIndex = Math.Max(1, pageIndex);
    pageSize = Math.Clamp(pageSize, 1, 100); // 限制最大页大小,防止一次性加载过多数据

    // 后续查询逻辑...
}

4. Blazor组件端调用示例

在Blazor组件中调用分页接口,实现分页控件交互:

@page "/server-list"
@inject IServerNameService ServerNameService

<h3>服务器列表</h3>

<!-- 分页控件 -->
<div class="pagination-controls">
    <span>总条数: @_pagedResult.TotalCount | 总页数: @_pagedResult.TotalPages | 当前页: @_pagedResult.PageIndex</span>
    <button disabled="@(_pagedResult.PageIndex <= 1)" @onclick="() => LoadPage(_pagedResult.PageIndex - 1)">上一页</button>
    <button disabled="@(_pagedResult.PageIndex >= _pagedResult.TotalPages)" @onclick="() => LoadPage(_pagedResult.PageIndex + 1)">下一页</button>
</div>

<!-- 数据表格 -->
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>服务器名称</th>
            <th>服务器类型</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var server in _pagedResult.Items)
        {
            <tr>
                <td>@server.Id</td>
                <td>@server.ServerName</td>
                <td>@server.ServerTypeName</td>
            </tr>
        }
    </tbody>
</table>

@code {
    private PagedResult<ServerNameWithTypeDto> _pagedResult = new();
    private const int DefaultPageSize = 10;

    protected override async Task OnInitializedAsync()
    {
        await LoadPage(1);
    }

    private async Task LoadPage(int pageIndex)
    {
        _pagedResult = await ServerNameService.GetAll(pageIndex, DefaultPageSize);
        StateHasChanged();
    }
}

关键注意事项

  • 必须使用IQueryable:确保EF Core能将Skip/Take逻辑翻译成SQL语句,实现真正的服务端分页,避免先加载全量数据到内存再分页的性能问题。
  • 避免提前触发查询:不要在分页前调用ToListAsync等方法,否则会转为内存分页。
  • 投影优先于Include:如果只需要部分字段,使用Select投影比Include更高效,EF会自动生成精简的关联查询SQL。

内容的提问来源于stack exchange,提问作者ahmed abdelaziz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:52