'EntityFramework Core automatic migrations
Is there any code to perform automatic migration in Entity Framework core code first in asp.net core project?
I do it simply in MVC4/5 by adding
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDbContext, MyProject.Migrations.Configuration>());
public Configuration() {
AutomaticMigrationsEnabled = true;
}
This saves time when entities changed
Solution 1:[1]
You can call context.Database.Migrate()in your Startup.cs
eg:
using (var context = new MyContext(...))
{
context.Database.Migrate();
}
Solution 2:[2]
EF core doesn't support automatic migrations.So you have to do it manually.
From the perspective of automatic migrations as a feature, we are not planning to implement it in EF Core as experience has showed code-base migrations to be a more manageable approach.
You can read full story here : Not to implement Automatic Migrations
Solution 3:[3]
This is the way they do it in IdentityServer4 http://identityserver.io
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// this will do the initial DB population
InitializeDatabase(app);
}
private void InitializeDatabase(IApplicationBuilder app)
{
using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
scope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
...
}
}
Solution 4:[4]
Automatic migrations is not supported in EF Core. Migration it is necessary to create hands. To automatically apply all existing handmade migrations need to add the following code in the class Program:
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<MyDbContext>();
context.Database.Migrate(); // apply all migrations
SeedData.Initialize(services); // Insert default data
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
Solution 5:[5]
Following Microsoft's documentation
https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro
If you are using dependency injection, first, you need to setup a static class Data/DbInitializer.cs and add the following code:
public static class DbInitializer
{
public static void Initialize(ApplicationDbContext context)
{
context.Database.Migrate();
// Add Seed Data...
}
}
Notice, this is also where you can add seed data.
Next, in your Program.cs file, add the following code
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var environment = services.GetRequiredService<IHostingEnvironment>();
if (!environment.IsDevelopment())
{
var context = services.GetRequiredService<ApplicationDbContext>();
DbInitializer.Initialize(context);
}
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
In my case, I'm checking the environment to make sure I'm in development so I can control the migrations/updates. However, in production, I want them to be automatic for continuous integration. As others have mentioned, this is probably not best practices but on small projects it works great.
Solution 6:[6]
My working automigration code Asp Net Core 2.0.7.
// startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// configure app
SeedData.Initialize(app.ApplicationServices);
}
// dbInitializer.cs
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var serviceScope = serviceProvider.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
// auto migration
context.Database.Migrate();
// Seed the database.
InitializeUserAndRoles(context);
}
}
private static void InitializeUserAndRoles(ApplicationDbContext context)
{
// init user and roles
}
}
Solution 7:[7]
You can call Database.Migrate() in db context constructor.
Solution 8:[8]
If the model changes a lot and you manage a medium - large team, migrations leads more problems than solution at least in development phase. I published a nuget package with automatic migration for .net core, EFCore.AutomaticMigrations - https://www.nuget.org/packages/EFCore.AutomaticMigrations/, so manual migration not needed anymore.
You can call directly in Program class, like bellow:
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<Program>();
try
{
var environment = services.GetRequiredService<IWebHostEnvironment>();
if (environment.IsDevelopment())
{
var context = services.GetRequiredService<ApplicationContext>();
MigrateDatabaseToLatestVersion.ExecuteAsync(context).Wait();
}
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred creating/updating the DB.");
}
}
host.Run();
}
Solution 9:[9]
Frank Odoom's answer works even 4 years later in .net 5, but it is not the intended context to call the migration at runtime... And, it appears it never was because it requires us to mock the DbContext with DbContextOptions whos documentation explicitly states:
Here is my suggestion:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// database provider is configured before runtime migration update is applied e.g:
optionsBuilder.UseSqlServer(ConnectionString);
Database.Migrate();
}
Edit: My suggestion is actually horrible if you are using multiple DBContexts in the same project... It would migrate the database multiple times. Which would most likely not break anything, but it would slow startup considerably.
Solution 10:[10]
my best advice is not to use the automatic migration.It is always better to add migrations manually and also avoid bulk migration and stick to best practice for using manual migration
automatic migration is not a magic tool and there will be several occasions where you might want to add some addition changes to the migration. You only accomplish by using manual migration.
To enable migration, type "enable-migrations" in the package manager console
This way you will have full control of upgrading or downgrading your database and also easy to track migrations.
Just three simple steps in package manager console.
1) add-migrations [some name for your migration]
2) migrations is generated for the changes, you review them and also can make changes to it
3) update-database your migration is complete now.
handling migration is less painful!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Frank Odoom |
| Solution 2 | Sampath |
| Solution 3 | Matt Morgan |
| Solution 4 | |
| Solution 5 | Amac |
| Solution 6 | dev-siberia |
| Solution 7 | Evgeniy P |
| Solution 8 | |
| Solution 9 | |
| Solution 10 |
