How to Add an implementation of 'IDesignTimeDbContextFactory<DataContext>' to the project in asp.net-core-2.0

34k views Asked by At

Here are the list of packages which I have installed : Installed Packages

I am using Entityframework core 2.0. First time I have successfully created database using entity framework code first migration(add-migration and update-database command). Now when I update my entities and try to run migration it's giving me following error.

Unable to create an object of type 'DataContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

Here is my code ...

Program.cs

public static void Main(string[] args)
{
    BuildWebHost(args).Run();
}

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

Startup.cs

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

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Repositories

    services.AddMvc();
    services.AddDbContextPool<DataContext>(
        options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        //options => options.UseSqlServer(@"Server=LAPTOP-518D8067;Database=Gyanstack;Trusted_Connection=True;MultipleActiveResultSets=true"));

    services.AddCors();
    services.AddScoped<ISectionRepository, SectionRepository>();
    services.AddScoped(typeof(IEntityBaseRepository<>), typeof(EntityBaseRepository<>));
}

DataContext.cs

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) 
        : base(options)
    { }

    public DbSet<Section> Section { get; set; }
    public DbSet<SubSection> SubSection { get; set; }
    public DbSet<Article> Article { get; set; }
    public DbSet<Comment> Comment { get; set; }
    public DbSet<User> User { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.AddConfiguration(new SectionMap());
        modelBuilder.AddConfiguration(new SubSectionMap());
        modelBuilder.AddConfiguration(new ArticleMap());
        modelBuilder.AddConfiguration(new CommentMap());
    }
}
11

There are 11 answers

4
gbjbaanb On

EDIT: now obsolete. Microsoft updated their migration document at the end of September to show how to update so you do not need this workaround.

As seen on this issue I raised on github, you move your DB initialisation code to the Program main, putting it in between BuildWebHost() and .Run()

Its relatively easy once you understand you need to get the DB context using var context = services.GetRequiredService<MyContext>(); in Main and then everything works as expected. (though I still think DB initialisation is a one-time initialisation thing, not an every-program-run thing)

0
Nick G. On

The problem is with seeding db from Startup.Configure... you can still do it with this work around. Tested and worked fine

https://garywoodfine.com/how-to-seed-your-ef-core-database/

0
Pavel K. On

I had the same issue on latest .Net Core 2.0.3. I have separate project with dbContext implementation (from my custom interface IUnitOfWork), and at first - migration was worked perfectly. But after I have implemented some other infrastructure - I have got the similar error:

Unable to create an object of type 'TestCoreUnitOfWork'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

The suggested solution about implementation IDesignTimeDbContextFactory is fine, but I was wondering why migrations have worked before? I have spent few hours, to find out, which code change was break the migration. And as it turned out, it was initialization of bootstrappers, where I have load all referenced assemblies (via Assembly.Load()) from my solution. After I have changed this to more traditional way with direct call of all bootstrappers - migration began to work again.

To sum up and answering for the question, the one is possible reason of the migration error - using Assembly.Load() in the StartUp.ConfigureServices().

I hope it will be useful to someone.

0
sibvic On

It look like EF 2.0 don't work with "sample data" which remains from the old net core template of the project. I managed to get rid of this error just commenting the next line:

SampleData.Initialize(app.ApplicationServices);

I think

var context = serviceProvider.GetService<ApplicationDbContext>();
context.Database.Migrate();

cases this error. I'm not sure whether this fix is correct but it works.

2
Tobias Punke On

This is related to the new init process of .NET Core 2.0, in which the configuration is handled differently (details here).

If you upgraded from 1.x, modify your Program.cs and Startup.cs:

public class Program
{
    public static void Main(String[] args)
    {
        Program.BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(String[] args) =>
        WebHost.CreateDefaultBuilder(args)
               .UseKestrel()
               .UseUrls("http://*:8000")
               .UseStartup<Startup>()
               .Build();
}

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

    public IConfiguration Configuration { get; }

    ........
}

After this modification your migrations should work and there is no need for an implementation of IDesignTimeDbContextFactory.

0
Kristoffer Jälén On

In 2.0 projects, move the SeedData.Initialize call to the Main method of Program.cs:

var host = BuildWebHost(args);

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

    try
    {
        SeedData.Initialize(services, "").Wait();
    }
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "An error occurred seeding the DB.");
    }
}

host.Run();   

Reference: https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#move-database-initialization-code

0
Delisay suse baldaji On

Some people said that you have to change your Startup.cs class, but I din't do nothing of that, just changed a little my Program.cs class

----------Old file--------------

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

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

            try
            {
                var context = services.GetRequiredService<MvcMovieContext>();
                context.Database.Migrate();
                SeedData.Initialize(services);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }

        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

----------New File---------

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

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {
                var dbContext = scope.ServiceProvider.GetService<MvcMovieContext>();
                //SeeData is a class in my Models folder
                SeedData.Initialize(services);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }
        host.Run();
    }

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

For me I made the my DBContext class with Constructor Injection and it give this error. I reverted back to have parameterless constructor than it work.

0
Franfy On

[For version 2.1.1]

I added method OnConfiguring in MyDbContext.cs:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
 optionsBuilder.UseSqlServer(@"Server(localdb)\\mssqllocaldb;Database=MyDataBase;Trusted_Connection=True;MultipleActiveResultSets=truer");
}
0
mkb On

I came across with this error while using Npgsql.EntityFrameworkCore.PostgreSQL, if it matters.

Taking in account https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers

I added this to BuildWebHost()

.ConfigureAppConfiguration((hostContext, config) =>
{
    // delete all default configuration providers
    config.Sources.Clear();
    config.AddJsonFile("appsettings.json", optional: true);
})

so it bacame:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureAppConfiguration((hostContext, config) =>
    {
        // delete all default configuration providers
        config.Sources.Clear();
        config.AddJsonFile("appsettings.json", optional: true);
    })
    .Build();

Now it works

0
Srinivas Mohan Pillalamarrri On

Simply changed my Program.cs

from this

public class Program
{
  public static void Main(string[] args)
  {
    var host = new WebHostBuilder()
      .UseKestrel()
      .UseContentRoot(Directory.GetCurrentDirectory())
      .UseIISIntegration()
      .UseStartup<Startup>()
      .Build();

    host.Run();
  }
}

to this

public class Program
{
  public static void Main(string[] args)
  {
    BuildWebHost(args).Run();
  }

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

Source: https://wildermuth.com/2017/07/06/Program-cs-in-ASP-NET-Core-2-0