03/11/2022 - Dotnet 6.0
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.
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>
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}");
}
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
- dotnet/EntityFramework.Docs#933
- https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Schemas/TwoProjectMigrations
- https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/projects?tabs=dotnet-core-cli
- https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/providers?tabs=dotnet-core-cli
- https://stackoverflow.com/questions/56702683/no-migrations-were-applied-the-database-is-already-up-to-date-done