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

ABP.IO:如何无需分页获取ReadOnlyAppService的全部数据?

问题描述

我通过ReadOnlyAppService将NetworkDevice对象暴露给Angular前端,编写的AppService如下:

public class NetworkDeviceAppService: ReadOnlyAppService<NetworkDevice, NetworkDeviceDto, Guid>, INetworkDeviceAppService
{
    public NetworkDeviceAppService(IReadOnlyRepository<NetworkDevice, Guid> repository) : base(repository)
    {
    }
}

但Angular客户端调用时必须传入PagedAndSortedResultRequestDto才能获取数据:

private getNetworkDevices() {
  let request = new PagedAndSortedResultRequestDto();
  this.networkDeviceService
    .getList(request)
    .subscribe(res => {
      this.networkDevices = res.items;
    })
}

我不想指定maxResultCount,希望直接获取全部数据,目前想到的方案都不够优雅:

  • 传入2000000作为maxResultCount
  • 在NetworkDeviceAppService中添加public async Task<IListResult<NetworkDeviceDto>> GetAllAsync()方法
  • 在客户端循环请求数据

想知道是否存在无需PagedAndSortedResultRequestDto的等效ReadOnlyAppService,或者更优雅的实现方式?


优雅实现方案

方案1:重写GetListAsync,兼容无分页逻辑

利用ABP框架的扩展能力,重写基类的GetListAsync方法,通过约定值(比如-1)触发全量数据返回,既保留原有分页逻辑的兼容性,又能实现无分页获取:

public class NetworkDeviceAppService: ReadOnlyAppService<NetworkDevice, NetworkDeviceDto, Guid>, INetworkDeviceAppService
{
    public NetworkDeviceAppService(IReadOnlyRepository<NetworkDevice, Guid> repository) : base(repository)
    {
    }

    public override async Task<PagedResultDto<NetworkDeviceDto>> GetListAsync(PagedAndSortedResultRequestDto input)
    {
        // 当maxResultCount为-1时,返回全部数据
        if (input.MaxResultCount == -1)
        {
            var entities = await Repository.GetListAsync();
            var dtos = ObjectMapper.Map<List<NetworkDevice>, List<NetworkDeviceDto>>(entities);
            return new PagedResultDto<NetworkDeviceDto>(dtos.Count, dtos);
        }
        // 否则沿用原有分页逻辑
        return await base.GetListAsync(input);
    }
}

前端调用时只需传入约定值:

private getNetworkDevices() {
  let request = new PagedAndSortedResultRequestDto();
  request.maxResultCount = -1; // 标记获取全量数据
  this.networkDeviceService
    .getList(request)
    .subscribe(res => {
      this.networkDevices = res.items;
    })
}

方案2:添加标准全量获取接口

如果希望明确区分分页和全量接口,可以添加符合ABP规范的GetAllAsync方法,借助框架的自动映射能力保证代码简洁:

public class NetworkDeviceAppService: ReadOnlyAppService<NetworkDevice, NetworkDeviceDto, Guid>, INetworkDeviceAppService
{
    public NetworkDeviceAppService(IReadOnlyRepository<NetworkDevice, Guid> repository) : base(repository)
    {
    }

    public async Task<IListResult<NetworkDeviceDto>> GetAllAsync()
    {
        var entities = await Repository.GetListAsync();
        var dtos = ObjectMapper.Map<List<NetworkDevice>, List<NetworkDeviceDto>>(entities);
        return new ListResultDto<NetworkDeviceDto>(dtos);
    }
}

同时在接口中声明该方法:

public interface INetworkDeviceAppService : IReadOnlyAppService<NetworkDeviceDto, Guid>
{
    Task<IListResult<NetworkDeviceDto>> GetAllAsync();
}

前端直接调用新接口即可:

private getNetworkDevices() {
  this.networkDeviceService
    .getAll()
    .subscribe(res => {
      this.networkDevices = res.items;
    })
}

方案3:封装通用全量只读基类

如果多个业务服务都需要全量获取能力,可以封装通用基类避免重复代码:

public class FullReadOnlyAppService<TEntity, TEntityDto, TKey> : ReadOnlyAppService<TEntity, TEntityDto, TKey>
    where TEntity : class, IEntity<TKey>
    where TEntityDto : IEntityDto<TKey>
{
    public FullReadOnlyAppService(IReadOnlyRepository<TEntity, TKey> repository) : base(repository)
    {
    }

    public virtual async Task<IListResult<TEntityDto>> GetAllAsync()
    {
        var entities = await Repository.GetListAsync();
        var dtos = ObjectMapper.Map<List<TEntity>, List<TEntityDto>>(entities);
        return new ListResultDto<TEntityDto>(dtos);
    }
}

后续业务服务直接继承该基类即可:

public class NetworkDeviceAppService: FullReadOnlyAppService<NetworkDevice, NetworkDeviceDto, Guid>, INetworkDeviceAppService
{
    public NetworkDeviceAppService(IReadOnlyRepository<NetworkDevice, Guid> repository) : base(repository)
    {
    }
}

内容的提问来源于stack exchange,提问作者Damien R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:00:58