Aspnetcore: How to correctly seed a DbContext using ASP.NET Core 2.0?

Created on 6 Sep 2017  路  7Comments  路  Source: dotnet/aspnetcore

Hello, dear friends in ASP.NET!

I haven't found any information and this is a so common task that I'm almost forced to ask you to, please, give a helping hand to people like me, that are trying to get into the ASP.NET Core ship.

What I'm trying to do is to seed my database with sample data. I haven't found a nice place to perform this startup task. However, some people says the Startup.Configure can be a right place.

However, after following the advice, I have faced some problems with the resolution of the DbContext.

This is my Startup class:

    public abstract class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<SGDTPContext>(options => options.UseInMemoryDatabase("MyDatabase"));
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();

            SeedDatabase(app);
        }

        private static void SeedDatabase(IApplicationBuilder app)
        {
            using (var context = app.ApplicationServices.GetRequiredService<SGDTPContext>())
            {
                // Seed the Database
                //... 
            }
        }
    }

As usual, I register my DbContext in ConfigureServices. But after that, in the Startup.Configure method, when I try to resolve it using GetRequiredService, it throws with this message:

System.InvalidOperationException: 'Cannot resolve scoped service 'SGDTP.Infrastructure.Context.SGDTPContext' from root provider.'

I've also posted this as a question in StackOverflow: https://stackoverflow.com/questions/46063945/cannot-resolve-dbcontext-in-asp-net-core-2-0

Big thanks for the help, in advance.

Most helpful comment

I wrote a blog post based on information I found in issues here, can't remember the specific issue where I saw it but my understanding is seeding and running migrations should now be done in Program.cs not in startup. like this:

public class Program
{
    public static void Main(string[] args)
    {
        var host = BuildWebHost(args);

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                EnsureDataStorageIsReady(services);

            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred while migrating the database.");
            }
        }

        host.Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

    private static void EnsureDataStorageIsReady(IServiceProvider services)
    {
        CoreEFStartup.InitializeDatabaseAsync(services).Wait();
        SimpleContentEFStartup.InitializeDatabaseAsync(services).Wait();
        LoggingEFStartup.InitializeDatabaseAsync(services).Wait();
    }

}

All 7 comments

@bricelam where is the guidance for moving this to Main?

I'm not sure where/if it got documented...

@divega might know.

I wrote a blog post based on information I found in issues here, can't remember the specific issue where I saw it but my understanding is seeding and running migrations should now be done in Program.cs not in startup. like this:

public class Program
{
    public static void Main(string[] args)
    {
        var host = BuildWebHost(args);

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                EnsureDataStorageIsReady(services);

            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred while migrating the database.");
            }
        }

        host.Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

    private static void EnsureDataStorageIsReady(IServiceProvider services)
    {
        CoreEFStartup.InitializeDatabaseAsync(services).Wait();
        SimpleContentEFStartup.InitializeDatabaseAsync(services).Wait();
        LoggingEFStartup.InitializeDatabaseAsync(services).Wait();
    }

}

just found the issue with the guidance forgot I linked it from my post
https://github.com/aspnet/Docs/issues/3864

This is the issue I created asking for this to be covered in the 1.x-to-2.x migration documentation:

https://github.com/aspnet/Docs/issues/4134

@joeaudette feel free to up-vote.

This issue is being closed because it has not been updated in 3 months.

We apologize if this causes any inconvenience. We ask that if you are still encountering this issue, please log a new issue with updated information and we will investigate.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guardrex picture guardrex  路  3Comments

ermithun picture ermithun  路  3Comments

farhadibehnam picture farhadibehnam  路  3Comments

BrennanConroy picture BrennanConroy  路  3Comments

aurokk picture aurokk  路  3Comments