Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you configure the DbContext when creating Migrations in Entity Framework Core?

Is there way that dependency injection can be configured/bootstrapped when using Entity Framework's migration commands?

Entity Framework Core supports dependency injection for DbContext subclasses. This mechanism includes allowing for configuration of data access outside of of the DbContext.

For example, the following would configure EF to persist to a SQL server using a connection string retrieved from config.json

ServiceCollection services = ...

var configuration = new Configuration().AddJsonFile( "config.json" );
services.AddEntityFramework( configuration )
    .AddSqlServer()
    .AddDbContext<BillingDbContext>( config => config.UseSqlServer() );

However, the migrations commands do not know to execute this code so Add-Migration will fail for lack of a provider or lack of a connection string.

Migrations can be made to work by overriding OnConfiguring within the DbContext subclass to specify the provider and configuration string, but that gets in the way when different configuration is desired elsewhere. Ultimately keeping my the migration commands and my code both working becomes undesirably complex.

Note: My DbContext lives in a different assembly than the entry point that uses it and my solution has multiple start-up projects.

like image 326
vossad01 Avatar asked Mar 17 '15 21:03

vossad01


People also ask

How do you specify context in migration?

Using multiple context types One way to create multiple migration sets is to use one DbContext type per provider. Specify the context type when adding new migrations. You don't need to specify the output directory for subsequent migrations since they are created as siblings to the last one.

How does DbContext work in Entity Framework?

It is a bridge between your domain or entity classes and the database. DbContext is the primary class that is responsible for interacting with the database. It is responsible for the following activities: Querying: Converts LINQ-to-Entities queries to SQL query and sends them to the database.

How does DbContext work in .NET core?

An instance of DbContext represents a session with the database which can be used to query and save instances of your entities to a database. DbContext is a combination of the Unit Of Work and Repository patterns. DbContext in EF Core allows us to perform following tasks: Manage database connection.

What is DbContext in Entity Framework Core?

A DbContext instance represents a session with the database and can be used to query and save instances of your entities. DbContext is a combination of the Unit Of Work and Repository patterns. Entity Framework Core does not support multiple parallel operations being run on the same DbContext instance.


2 Answers

If you are looking for a solution to configure context for migrations, you can use this in your DBContext class:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
            var connectionString = configuration.GetConnectionString("DbCoreConnectionString");
            optionsBuilder.UseSqlServer(connectionString);
        }
    }

Remember to install those two packages to have SetBasePath and AddJsonFile methods: Microsoft.Extensions.Configuration.FileExtensions

Microsoft.Extensions.Configuration.Json

like image 86
Mik Avatar answered Oct 13 '22 01:10

Mik


As @bricelam commented this functionality does not yet exist in Entity Framework 7. This missing functionality is tracked by GitHub issue aspnet/EntityFramework#639

In the mean time, the easier workaround I found was to utilize a global state rather than hassle with subclassing. Not usually my first design choice but it works well for now.

In MyDbContext:

public static bool isMigration = true;

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
    // TODO: This is messy, but needed for migrations.
    // See https://github.com/aspnet/EntityFramework/issues/639
    if ( isMigration )
    {
        optionsBuilder.UseSqlServer( "<Your Connection String Here>" );
    }
}

In Startup.ConfigureServices().

public IServiceProvider ConfigureServices( IServiceCollection services )
{
    MyContext.isMigration = false;

    var configuration = new Configuration().AddJsonFile( "config.json" );
    services.AddEntityFramework( configuration )
        .AddSqlServer()
        .AddDbContext<MyDbContext>( config => config.UseSqlServer() );
    // ...
}

(The configuration code actually lives in an Autofac Module in my case.)

like image 24
vossad01 Avatar answered Oct 13 '22 01:10

vossad01