是否可以在 HotChocolate 中创建通用数据加载器?

问题描述

我正在尝试为我以通用方式提供的任何实体创建一个具有标准查询和突变的 graphql 服务器,即我从某处读取配置,在内存中创建实体,然后创建 graphql 服务器。

我目前能够创建一个通用类型来查询所有详细信息,但我似乎无法创建一个通用数据加载器来有效地按 Id 检索记录。

query GetSpecificSpeakerById {
  byId(id: 1) {
    name
  }
}

query GetSpecificSpeakerById {
  a: byId(id: 1) {
    name
  }
  b: byId(id: 2) {
    name
  }
}

模式似乎正确生成,但我在执行查询时收到以下信息:

{
  "name": "ServerError","statusCode": 500,"statusText": "Internal Server Error","bodyText": "{\"errors\":[{\"message\":\"The ID \\u00601\\u0060 has an invalid format.\"}]}"
}

我目前有以下代码:

startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddPooledDbContextFactory<ApplicationDbContext>(options => 
            options.UseSqlite("Data Source=conferences.db"));

        var entityType = typeof(Speaker);            
        Type queryType = typeof(GenericQuery<>).MakeGenericType(entityType);

        Type dataLoaderType = typeof(GenericrByIdDataLoader<>).MakeGenericType(entityType);

        services
                .AddGraphQLServer()
                .AddQueryType(queryType)
                .AddDataLoader<GenericrByIdDataLoader<Speaker>>();                   
    }

GenericByIdDataLoader.cs

public class GenericrByIdDataLoader<TEntity> : BatchDataLoader<int,TEntity>
        where TEntity : class,IEntity
    {
        private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;

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

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

            return await dbContext.Set<TEntity>()
                .Where(s => keys.Contains(s.Id))
                .ToDictionaryAsync(t => t.Id,cancellationToken);
        }
    }

GenericQuery.cs

public class GenericQuery<TEntity> 
    where TEntity : class,IEntity
{       
    [UseApplicationDbContext]
    public async Task<List<TEntity>> GetAll([ScopedService] ApplicationDbContext context)
    {
        return await context.Set<TEntity>().AsNoTracking().ToListAsync();
    }

    public Task<TEntity> GetByIdAsync(
        [ID(nameof(TEntity))] int id,GenericrByIdDataLoader<TEntity> dataLoader,CancellationToken cancellationToken)
    {
        return dataLoader.LoadAsync(id,cancellationToken);
    }
}

IEntity.cs

public interface IEntity
    {
        int Id { get; set; }
    }

Speaker.cs

public class Speaker : IEntity
    {
        public int Id { get; set; }

        [Required]
        [StringLength(200)]
        public string? Name { get; set; }

        [StringLength(4000)]
        public string? Bio { get; set; }

        [StringLength(1000)]
        public virtual string? WebSite { get; set; }
    }

知道是什么问题吗?

谢谢

解决方法

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

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

小编邮箱: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...