Skip to content

Instantly share code, notes, and snippets.

@thewrath
Last active November 4, 2022 16:18
Show Gist options
  • Save thewrath/a6b735efccff34230ceb3ca11a2d9cb4 to your computer and use it in GitHub Desktop.
Save thewrath/a6b735efccff34230ceb3ca11a2d9cb4 to your computer and use it in GitHub Desktop.

Separate migrations for multiple providers

03/11/2022 - Dotnet 6.0

Goal

Inspired by this documentation Separate Migrations, the goal is to have a migration suite for Sqlite (used in dev) and another one for SqlServer (used in production). This document gathers what in my case brought me a working solution.

Projects setup

We assume that your project contains a sln file, the objective is as follows:

  • MyApp -> the root folder, it contains the .sln file
  • MyApp/MyApp.Web -> contains the ASP application created with dotnet new
  • MyApp/MyApp.SqliteMigrations -> class library which will contain the Sqlite specific migrations. (we will create it)
  • MyApp/MyApp.SqlServerMigrations -> class library which will contain SqlServer specific migrations. (we will create it)

All the following command are executed from the project solution root dir (in my case ./MyApp).

Create Class library for each providers

dotnet new classlib -o MyApp.SqliteMigrations
dotnet sln add .\MyApp.SqliteMigrations\MyApp.SqliteMigrations.csproj
dotnet new classlib -o MyApp.SqlServerMigrations
dotnet sln add .\MyApp.SqlServerMigrations\MyApp.SqlServerMigrations.csproj

Add reference from migrations class library to the main project (MyApp.Web)

dotnet add .\MyApp.SqliteMigrations\MyApp.SqliteMigrations.csproj reference .\MyApp.Web\MyApp.Web.csproj
dotnet add .\MyApp.SqlServerMigrations\MyApp.SqlServerMigrations.csproj reference .\MyApp.Web\MyApp.Web.csproj

You also need to add the following line into MyApp.SqlServerMigrations\MyApp.SqlServerMigrations.csproj and MyApp.SqliteMigrations\MyApp.SqliteMigrations.csproj

<PropertyGroup>
    <BaseOutputPath>..\MyApp.Web\bin\</BaseOutputPath>
</PropertyGroup>

DbContext configuration

var provider = configuration.GetValue("DatabaseProvider", "Sqlite"); // Sqlite as default

// Custom DbContext configuration based on the DBMS (See: https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/providers?tabs=dotnet-core-cli)
switch (provider)
{
    case "Sqlite":
        services.AddDbContext<ApplicationContext>(options =>
        {
            options.UseSqlite(configuration.GetConnectionString("SqliteConnection"), builder =>
            {
                builder.MigrationsAssembly("MyApp.SqliteMigrations");
            });
        });
        break;
    case "SqlServer":
        services.AddDbContext<ApplicationContext>(options =>
        {
            options.UseSqlServer(configuration.GetValue<string>("SqlServerConnection"), builder =>
            {
                builder.MigrationsAssembly("MyApp.SqlServerMigrations");
            });
        });
        break;
    default:
        throw new Exception($"Unsupported provider: {provider}");
}

Generate migrations

For Sqlite:

cd MyApp.SqliteMigrations
dotnet ef migrations add InitialCreate --startup-project ..\MyApp.Web

For SqlServer:

cd MyApp.SqlServerMigrations
dotnet ef migrations add InitialCreate --startup-project ..\MyApp.Web -- --DatabaseProvider SqlServer

When migrations are up to date for all your providers you can update your database (from this StackOverflow).

dotnet build // Rebuild the whole project solution
cd MyApp.Web
dotnet ef database update // Sqlite is the default provider in my case
dotnet ef database update -- --DatabaseProvider SqlServer // for SqlServer provider

Ressources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment