中继分页、数据加载器和内存中的斩波

问题描述

我是 graphql 的新手,目前正在参加 ChilliCream graphql 研讨会。遵循this

后实现分页后

有一条注释:“在我们使用 TrackType 的实现中有一个警告。因为,我们在解析器中使用了 DataLoader 并首先获取 ID 列表,所以我们基本上将始终获取所有内容并切入内存。在一个实际的项目,这可以通过将 DataLoader 部分移动到中间件和可查询 id 上的第一页来分为两个操作。也可以实现一个特殊的 IPagingHandler,它使用 DataLoader 并应用分页逻辑。”

我一直无法弄清楚如何拆分这两个操作。任何帮助将不胜感激。

查询

query GetTrackWithSessions {
  trackById(id: "VHJhY2sKaTE=") {
    id
    sessions(first: 1) {      
      nodes {
        title
      }      
    }
  }
}

TrackQuery

public Task<Track> GetTrackByIdAsync(
            [ID(nameof(Track))] int id,TrackByIdDataLoader trackById,CancellationToken cancellationToken) =>
            trackById.LoadAsync(id,cancellationToken);

TrackType

public class TrackType : ObjectType<Track>
    {
        protected override void Configure(IObjectTypeDescriptor<Track> descriptor)
        {
            descriptor
                .ImplementsNode()
                .IdField(t => t.Id)
                .ResolveNode((ctx,id) =>
                    ctx.DataLoader<TrackByIdDataLoader>().LoadAsync(id,ctx.RequestAborted));

            descriptor
                .Field(t => t.Sessions)
                .ResolveWith<TrackResolvers>(t => t.GetSessionsAsync(default!,default!,default))
                .UseDbContext<ApplicationDbContext>()
                .UsePaging<NonNullType<SessionType>>()
                .Name("sessions");

            descriptor
                .Field(t => t.Name)
                .UseUpperCase();
        }

        private class TrackResolvers
        {
            public async Task<IEnumerable<Session>> GetSessionsAsync(
                Track track,[ScopedService] ApplicationDbContext dbContext,SessionByIdDataLoader sessionById,CancellationToken cancellationToken)
            {
                int[] sessionIds = await dbContext.Sessions
                    .Where(s => s.Id == track.Id)
                    .Select(s => s.Id)
                    .ToArrayAsync();

                return await sessionById.LoadAsync(sessionIds,cancellationToken);
            }
        }
    }

数据加载器

public class TrackByIdDataLoader : BatchDataLoader<int,Track>
    {
        private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;

        public TrackByIdDataLoader(
            IBatchScheduler batchScheduler,IDbContextFactory<ApplicationDbContext> dbContextFactory)
            : base(batchScheduler)
        {
            _dbContextFactory = dbContextFactory ?? 
                throw new ArgumentNullException(nameof(dbContextFactory));
        }

        protected override async Task<IReadOnlyDictionary<int,Track>> LoadBatchAsync(
            IReadOnlyList<int> keys,CancellationToken cancellationToken)
        {
            await using ApplicationDbContext dbContext = 
                _dbContextFactory.CreateDbContext();

            *All the tracks are returned here
            return await dbContext.Tracks
                .Where(s => keys.Contains(s.Id))
                .ToDictionaryAsync(t => t.Id,cancellationToken);
        }
    }

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...