.NET 5.0 - Entity Framework Migrations for Multiple Databases (SQLite and SQL Server)
Example code tested with .NET 5.0
Other versions available:
- .NET: .NET 6.0
In this post we'll go through an example of how to setup a .NET 5.0 project with Entity Framework Migrations that supports multiple different database providers.
The code snippets in this post are taken from an example .NET API I posted recently that supports multiple databases for different environments, specifically SQLite in development and SQL Server in production. For more info or to download and test the API locally see .NET 5.0 - Simple API for Authentication, Registration and User Management.
The below steps show how to use a SQLite database in development and a SQL Server database in production, but you could change these to any other database providers that are supported by Entity Framework.
Create Main Entity Framework DbContext for SQL Server
Create the main database context class that defines the entities available in the database via public DbSet<TEntity>
properties, and configure it to connect to the production database (SQL Server in this case).
Below is the main database context from the example .NET 5.0 API linked above, it has the class name DataContext
and is located in the /Helpers
directory of the project, but you can choose any class name and directory you prefer.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using WebApi.Entities;
namespace WebApi.Helpers
{
public class DataContext : DbContext
{
protected readonly IConfiguration Configuration;
public DataContext(IConfiguration configuration)
{
Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sql server database
options.UseSqlServer(Configuration.GetConnectionString("WebApiDatabase"));
}
public DbSet<User> Users { get; set; }
}
}
Create Dev DbContext for SQLite
Create a development database context that inherits from the main context and changes the database provider by overriding the OnConfiguring()
method.
Below is the dev database context from the example .NET 5.0 API, it inherits from DataContext
above and changes the database provider to SQLite. Having a second Entity Framework Context that inherits from the main context is what enables the project to support multiple different databases.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace WebApi.Helpers
{
public class SqliteDataContext : DataContext
{
public SqliteDataContext(IConfiguration configuration) : base(configuration) { }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// connect to sqlite database
options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase"));
}
}
}
Generate SQLite Entity Framework Migrations
Run the following command to generate Entity Framework Migrations for SQLite and store them in their own folder.
dotnet ef migrations add InitialCreate --context SqliteDataContext --output-dir Migrations/SqliteMigrations
Generate SQL Server Entity Framework Migrations
Run the following command to generate Entity Framework Migrations for SQL Server and store them in their own folder.
The environment variable ASPNETCORE_ENVIRONMENT
needs to be set to Production
so the SQL Server DataContext
class is configured with the .NET dependency injection (DI) system, see the ConfigureServices()
method below.
Configuring environment variables from the command line is slightly different between Windows Command, Windows PowerShell and MacOS.
Windows Command
set ASPNETCORE_ENVIRONMENT=Production
dotnet ef migrations add InitialCreate --context DataContext --output-dir Migrations/SqlServerMigrations
Windows PowerShell
$env:ASPNETCORE_ENVIRONMENT="Production"
dotnet ef migrations add InitialCreate --context DataContext --output-dir Migrations/SqlServerMigrations
MacOS
ASPNETCORE_ENVIRONMENT=Production dotnet ef migrations add InitialCreate --context DataContext --output-dir Migrations/SqlServerMigrations
Configure Startup.cs to use SQLite in Development and SQL Server in Production
Below is a cut down version of the Startup.cs file from the example .NET 5.0 API that just includes the bits related to Entity Framework DbContext configuration and automatic database migration. The complete file is available here.
Lines 23 - 26
configure which type of data context is injected by the .NET dependency injection system when a DataContext
instance is required by a class. In production an instance of the main DataContext
class is used which connects to SQL Server, otherwise (i.e. in development) an instance of the SqliteDataContext
is used.
An instance of the DataContext
is injected as a parameter to the Configure()
method, the data context instance is then used to apply any pending migrations to the database by calling the dataContext.Database.Migrate()
method on line 35
.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApi.Helpers;
namespace WebApi
{
public class Startup
{
private readonly IWebHostEnvironment _env;
public Startup(IWebHostEnvironment env)
{
_env = env;
}
// add services to the DI container
public void ConfigureServices(IServiceCollection services)
{
// use sql server db in production and sqlite db in development
if (_env.IsProduction())
services.AddDbContext<DataContext>();
else
services.AddDbContext<DataContext, SqliteDataContext>();
...
}
// configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
// migrate any database changes on startup (includes initial db creation)
dataContext.Database.Migrate();
...
}
}
}
Need Some .NET Help?
Search fiverr for freelance .NET developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!