简体   繁体   中英

EF Core query on .NET Core webapi startup

Is there a way to perform a SQL query on web api startup through Entity Framework Core.

I need to load several background processes. Thanks!

Example: Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddDbContext<ApiContext>(
        options => options.UseSqlServer(
            Configuration.GetConnectionString("SqlServer"),          
            sqlServerOptionsAction: sqlOptions =>
                {
                     sqlOptions.EnableRetryOnFailure(
                         maxRetryCount: 3,
                         maxRetryDelay: TimeSpan.FromSeconds(5),
                         errorNumbersToAdd: null);
                }
        ));

    // ...
    var conts = await db.Conts.ListAsync();

    foreach(var c in conts)
    {             
        services.AddSingleton<IHostedService>(t => new Worker(c.id,(int)c.interval));
    }

    // ...
}

Create an extension of the BackgroundService class. Create/Inject a DbContext instance and do all your ef core work inside ExecuteAsync method of the BackgroundService .

So what you wanted to do is get the injected DbContext, right? If that's so, you cannot do that in your Startup.ConfigureServices . What you would need is a custom ProviderFactory class that will inherit from IServiceProviderFactory<IServiceCollection> :

internal class ApiServiceProviderFactory : IServiceProviderFactory<IServiceCollection>
{
    private readonly HostBuilderContext _builderContext;

    public ApiServiceProviderFactory([NotNull] HostBuilderContext hostBuilderContext)
    {
        _builderContext = hostBuilderContext;
    }

    public IServiceCollection CreateBuilder(IServiceCollection services)
    {
        return services;
    }

    public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)
    {
        var isDevelopment = _builderContext.HostingEnvironment.IsDevelopment();

        var options = new ServiceProviderOptions
        {
            ValidateOnBuild = isDevelopment,
            ValidateScopes = isDevelopment
        };

        var serviceProvider = containerBuilder.BuildServiceProvider(options);

        // var dbFactory = serviceProvider.GetRequiredService<IDbContextFactory<TContext>>();
        // using var context = dbFactory.CreateDbContext();
        

        return serviceProvider;
    }

I may be using the IDbContextFactory from my example, but this is similar. Then use your custom ProviderFactory class in your Program.cs

public static async Task Main(string[] args)
{
    await CreateHostBuilder(args)
        .UseServiceProviderFactory(context => new ApiServiceProviderFactory(context))
        .Build()
        .RunAsync();
}

I do this in Asp.Net Core Startup's Configure method, called after ConfigureServices. I add the db context as an additional method parameter, and DI provides the context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM