Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IDesignTimeDbContextFactory not always needed?

Previously i had to implement IDesignTimeDbContextFactory to get migrations running, e.g: PM > Add-Migration Initial PM > Update-Database

If not, the console threw an error and led me here: https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#use-idesigntimedbcontextfactory.

So i did what it suggested and got migrations running. After that i have created new projects, and i didn't have to implement the IDesignTimeDbContextFactory. Migrations worked anyway. How is this possible? Same .NET Core version (2.0) on all of the projects.

Do we always need to create a IDesignTimeDbContextFactory, or is it just in certain situations?

Thanks!

like image 781
Jan Banan Avatar asked Sep 14 '25 10:09

Jan Banan


2 Answers

Okay, here it goes: If you have a default constructor in your DbContext or are using the Program.BuildWebHost() pattern established in the ASP.NET Core 2.0 project templates, you typically won't need an IDesignTimeDbContextFactory implementation.

In 2.0.0-preview1 Program.BuildWebHost() wasn't used and you needed a design-time factory.

See this thread for full discussion: https://github.com/aspnet/EntityFrameworkCore/issues/9033

like image 129
Jan Banan Avatar answered Sep 17 '25 00:09

Jan Banan


As Dan Banan stated, if a DbContext has a default constructor, it won't need an IDesignTimeDbContextFactory at design time. However, if it needs to be configured from Startup, it will need a constructor which takes accepts DbContextOptions<T> and invokes the corresponding base constructor. However, this will create another issue. The DbContext's OnConfigure method will be called regardless of which constructor is used.

To account for these details, I've found the following pattern to be useful:

DbContext Configuration and Dependency Injection

serviceCollection
    .AddDbContext<MyDbContext>(
        options => options.UseSqlServer(configuration.GetConnectionString("MyDb"),
        ServiceLifetime.Transient
    );

MyDbContext.cs

public class MyDbContext : DbContext
{
    public SureshotDbContext()
    {
        // This allows for instantiation at design time.
    }

    public MyDbContext(DbContextOptions<MyDbContext> options) :
        base(options)
    {
        // This allows for configuration in real applications.
    }

    protected override void OnConfiguring(
        DbContextOptionsBuilder optionsBuilder
    )
    {
        if (optionsBuilder.IsConfigured)
        {
            return;
        }

        optionsBuilder.UseSqlServer(nameof(TDbContext));
    }
}
like image 24
cwharris Avatar answered Sep 17 '25 00:09

cwharris