In .Net 5, we use to be able to call the migration by passing DataContext to Configure method and call the migration in startup class.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
// migrate any database changes on startup (includes initial db creation)
dataContext.Database.Migrate();
...
}
How can we do it in .Net 6?
Short Version
It sounds like the real question is where to put code that used to live in Startup.Configure
.
In Program.cs
use
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>();
db.Database.Migrate();
}
Rather long explanation
The Applying Migrations at Runtime section in the EF Core Migrations docs shows that nothing's changed as far as EF Core is concerned.
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>();
//Same as the question
db.Database.Migrate();
}
host.Run();
}
It sounds like the real question is where to put code that used to live in Startup.Configure
. That code can be placed in the Main
method or, if Minimal APIs are used, inside Program.cs
. Configuration
, Services
, Environment
etc are available as properties in the WebApplicationBuilder class or the WebApplication created by it. WebApplicationBuilder
contains the builder interfaces for DI, configuration, Logging and the host, eg WebApplicationBuilder.Services
exposes IServiceCollection
.
WebApplication
properties expose the middleware configured by WebApplicationBuilder
, eg WebApplication.Services
exposes IServiceProvider
Startup replacement in Minimal APIs
The methods that were in Startup.cs
were merged in Program.cs
in .NET 6. Startup.cs contained two kinds of methods:
IServiceCollection
, IConfigurationBuilder
. This includes the code that used to be in Startup.ConfigureServices
.Startup.Configure
.In .NET 6, the interfaces move to the WebApplicationBuilder and WebApplication classes. Instead of .NET Core calling a "magic" Startup class and injecting the interfaces, the code in Program.cs
can access the interfaces it needs directly.
If you don't need to configure services, you can create a minimal API application with just 3 lines :
var app = WebApplication.Create(args);
app.MapGet("/", () => "Hello World!");
app.Run();
In your case you need to configure the DbContext at least, so you need to use WebApplicationBuilder
and WebApplication
separately. This is shown in the next section
Migrations in Minimal APIs
In the basic minimal API Program.cs
:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
DbContexts can be created once a WebApplication
instance is created through its Services
property:
var builder = WebApplication.CreateBuilder(args);
//Register the DbContexts etc.
...
builder.Services.AddDbContext<SomeDbContext>(....);
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>();
db.Database.Migrate();
}
app.MapGet("/", () => "Hello World!");
app.Run();
Of course it's a lot better to use separate methods or classes for such code, keeping Program.cs
clean :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<SomeDbContext>(....);
var app = builder.Build();
ApplyMigrations(app);
app.MapGet("/", () => "Hello World!");
app.Run();
static void ApplyMigrations(WebApplication app)
{
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>();
db.Database.Migrate();
}
Or even :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<SomeDbContext>(....);
var app = builder.Build();
app.ApplyMigrations()
.UseCustomLogging()
.DoSomeOtherConfiguration()
...;
app.MapGet("/", () => "Hello World!");
app.Run();
With ApplyMigrations
an extension method in a separate class :
public static DataExtensions
{
public static WebApplication ApplyMigrations(this WebApplication app)
{
using var scope = app.Services.CreateScope()
var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>();
db.Database.Migrate();
return app;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With