Entity Framework, автоматическое применение миграции
сначала я использую код Entity Framework и устанавливаю AutomaticMigrationsEnabled true этим кодом:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
public MigrateDBConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
в первом запуске проекта он работает нормально и создает базу данных и таблицы. после изменения модели и удаления некоторого поля или добавления новых полей и запуска Add-Migration создается класс миграции, но после запуска проекта это исключение:
исключение типа System.InvalidOperationException ' произошло в EntityFramework.dll, но не был обработан в user код
дополнительная информация: модель, поддерживающая контекст "DBContext", имеет изменилась с момента создания базы данных.
EDIT: как ответ Артуро Менчака я могу изменить код, как это:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());
...
но THS исключение ocure:
в базе данных уже есть объект с именем "MyTable".
Я хочу применить мою миграцию.
3 ответов
Автоматические Миграции означает, что вам не нужно работать add-migration
команда для ваших изменений в моделях, но вы должны запустить вручную.
если Автоматические Миграции включен при вызове update-database
, Если есть ожидающие изменения в ваших моделях, будет добавлена "автоматическая" миграция и база данных будет обновлена.
если вы хотите, чтобы ваша база данных обновляется без необходимости вызова , вы можете добавить Database.SetInitializer(...)
на OnModelCreating()
метод в вашем контексте, например:
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>
{
...
обратите внимание, что вы должны объявить DbMigrationsConfiguration
и MigrateDatabaseToLatestVersion
С вашим реальным контекстом, а не по умолчанию DbContext
.
наконец-то я нашел решение своей проблемы. Я вызываю этот метод в каждом запуске приложения:
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);
}
}
}
}
если у вас есть изменения в ваших сущностях, вам нужно сначала запустить add-migration
для создания сценария миграции.
после этого в Global.asax
вам нужно иметь такой код, как этот
var configuration = new MyProject.Configuration();
var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);
migrator.Update();
каждый раз, когда вы запускаете asp.net проект он проверит, есть ли у вас новая миграция для запуска и запуска update-database
автоматически для вас.