AddPooledDbContextFactory 与使用自定义 DbConnection 的 DbContext:服务未注册

问题描述

我有一个自定义的 DbContext SnowflakeDbContext,我需要用 SnowflakeDbConnection 初始化它才能工作:

    public class SnowflakeDbContext : DbContext
    {
        private readonly string connectionString = "";

        public SnowflakeDbContext(DbContextOptions<SnowflakeDbContext> options) : base(options)
        {

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            var dbConnection = new SnowflakeDbConnection()
            {
                ConnectionString = this.connectionString
            };
            optionsBuilder.UseSqlServer(dbConnection);
            optionsBuilder.AddInterceptors(new SnowflakeCommandInterceptor());
        }

        public DbSet<Opportunity> Opportunities { get; set; } = default!;
        public DbSet<Account> Accounts { get; set; } = default!;
    }

这适用于 EF Core 5,在 Startup.cs 中(我使用的是 ASP.NET Core 5 Web 应用程序)我使用

      .AddDbContext<SnowflakeDbContext>(ServiceLifetime.Singleton)

我想将 SnowflakeDbContextHotChocolate 一起使用,建议我使用 AddPooledDbContextFactory 以支持连接池并允许系统同时拨打电话(描述为 here)。

我已经修改了 Startup.cs:

        public void ConfigureServices(IServiceCollection services)
        {

            services
                .AddPooledDbContextFactory<SnowflakeDbContext>(options =>
                {
                    var dbConnection = new SnowflakeDbConnection()
                    {
                        ConnectionString = this.connectionString
                    };

                    options.UseSqlServer(dbConnection);
                    options.AddInterceptors(new SnowflakeCommandInterceptor());
                })
                .AddGraphQLServer()
                .AddQueryType<Query>();
        }

使用以下 GraphQL 查询(使用并行查询):

query GetAccountsInParallel {
  a: accounts {
    id,name
  }
  b: accounts {
    id,name
  }
  c: accounts {
    id,name
  }
}

我收到以下错误:

"No service for type 'SnowflakeGraphQL.Snowflake.SnowflakeDbContext' has been registered.",

我可以添加

      .AddDbContext<SnowflakeDbContext>()

在调用 .AddPooledDbContextFactory 之后的 Startup.cs 中。现在我得到一个不同的错误:

"A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext."

我在网上看到的所有示例都使用 .UseSqlServer(connectionString),因为我需要使用 .UseSqlServer(dbConnection) 版本才能成为能够访问我们的 Snowflake 数据库。

如何在 Startup.cs 中配置我的应用程序以使用 .AddPooledDbContextFactory()?

更新:从 graphql-workshop 代码开始,用第一个 SqlServer 替换 Sqlite,然后使用我的 SnowflakeDbContext 替换 SqlServer 我让它工作,所以我的代码中必须有一个细微的区别,如上所述以上导致我的情况失败。

解决方法

在检索帐户记录时,我们需要像这样使用 [ScopedService] 而不是 [Service]:

   [UseApplicationDbContext]
   public async Task<List<Account>> GetAccounts([ScopedService] SnowflakeDbContext context) => await context.Accounts.ToListAsync();

相关问答

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