I am using Entity Framework Code First approach with AutomaticMigrationsEnabled = true
:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
public MigrateDBConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
The first run of the project creates the database and tables as expected. After changing my model by adding or dropping fields, I ran Add-Migration
. The Migration class was generated but after running the project this exception occurs:
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code
Additional information: The model backing the 'DBContext' context has changed since the database was created.
EDIT: Per the guidance in the answer of arturo menchaca I changed my code like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());
...
After the change this exception is occurring:
There is already an object named 'MyTable' in the database.
How can I apply my database migration?
Automatic Migrations means that you don't need to run add-migration
command for your changes in the models, but you have to run update-database
command manually.
If Automatic Migrations is enabled when you call update-database
, if there are pending changes in your models, an 'automatic' migration will be added and database will be updated.
If you want that your database is updated without need to call update-database
command, you can add Database.SetInitializer(...)
in OnModelCreating()
method on your context, like so:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MigrateDBConfiguration>());
}
...
}
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<MyContext>
{
...
Note that you should declare DbMigrationsConfiguration
and MigrateDatabaseToLatestVersion
with your real context, not the default DbContext
.
Finally, I found a solution to my problem. I call this method in each application start :
public void InitializeDatabase(DataAccessManager context)
{
if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
{
var configuration = new DbMigrationsConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");
var migrations = migrator.GetPendingMigrations();
if (migrations.Any())
{
var scriptor = new MigratorScriptingDecorator(migrator);
var script = scriptor.ScriptUpdate(null, migrations.Last());
if (!string.IsNullOrEmpty(script))
{
context.Database.ExecuteSqlCommand(script);
}
}
}
}
If you have change in your entities, you need first run add-migration
to create the migration script.
After that in your Global.asax
you need to have some code like this
var configuration = new MyProject.Configuration();
var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);
migrator.Update();
every time that you run your asp.net project it'll check if you have a new migration to run and run update-database
automatically for you.
Microsoft addresses migrations at runtime, here .
For example, you can do this in Program.cs
: (tested working in .NET 5.0 preview)
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
MigrateDatabase(host);
host.Run();
}
private static void MigrateDatabase(IHost host)
{
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
await _dbContext.Database.MigrateAsync();
_dbContext.Database.Migrate();
OR
await _dbContext.Database.EnsureCreatedAsync();
_dbContext.Database.EnsureCreated();
both method check if database exist, if not they both create it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.