entity framework迁移 – 启用AutoMigrations以及添加的迁移

我正在我的项目中使用Entity Framework 4.3 Migrations。 我想使用自动迁移,这样当我修改我的域对象和我的上下文类时,我的数据库会在运行项目时自动更新。 到目前为止,我有这个工作。

除了自动迁移之外,我还想使用一些添加的迁移,我希望应用程序在运行应用程序时自动跳转到最新版本(基于我添加的迁移)。

为了做到这一点,我把它放在global.asax文件中……

Database.SetInitializer(new MigrateDatabaseToLatestVersion()); 

现在这样可行,但是当我这样做时,它不再根据我的域对象自动更新数据库。

我希望能够完全删除数据库,然后运行应用程序并运行所有自动迁移,然后运行我的显式迁移并将数据库升级到最新版本。

我知道我已经在之前的项目中使用了这个,但我不确定在这种情况下我做错了什么。

谢谢

您需要在构造函数中传递将AutomaticMigrationsEnabled设置为true的配置。 这样的事情应该有所帮助:

 Database.SetInitializer(new MigrateDatabaseToLatestVersion()); 

与MyConfiguration类似:

 public class MyConfiguration : Core.Migrations.Configuration { public MyConfiguration { this.AutomaticMigrationsEnabled = true; } } 

免责声明:刚刚入侵,所以可能需要进行小的调整才能编译

编辑:

只需检查EF 4.3.1,初始化程序的代码如下:

 Database.SetInitializer(new MigrateDatabaseToLatestVersion()); 

这对于配置类:

 public class MyConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration { public MyConfiguration() { this.AutomaticMigrationsEnabled = true; } } 

在对此进行了几个小时的讨论之后,我终于提出了一个解决方案,如果需要可以创建数据库, 或者如果过时则进行升级。 我们在Gallery Server Pro中使用此技术,以便第一次轻松安装或升级以前的版本。

 private static void InitializeDataStore() { System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion()); var configuration = new GalleryDbMigrationConfiguration(); var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration); if (migrator.GetPendingMigrations().Any()) { migrator.Update(); } } public sealed class GalleryDbMigrationConfiguration : DbMigrationsConfiguration { protected override void Seed(GalleryDb ctx) { MigrateController.ApplyDbUpdates(); } } 

我写了一篇博客文章,其中包含更多细节: 使用Entity Framework Code First Migrations自动创建和自动更新应用程序

这是我目前的解决方案,我并不完全满意。

 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); var context = new KCSoccerDataContext(); var initializeDomain = new CreateDatabaseIfNotExists(); var initializeMigrations = new MigrateDatabaseToLatestVersion(); initializeDomain.InitializeDatabase(context); initializeMigrations.InitializeDatabase(context); } 

我实际上创建了两个不同的初始化器。 第一个是使用CreateDatabaseIfNotExists,成功完成并根据我的Domain对象创建表。 第二个是使用MigrateDatabaseToLatestVersion执行我的所有显式迁移。

我不喜欢它,因为基本上禁用了自动迁移。 因此,为了添加或更改我的域模型,我必须完全删除数据库并重新创建它。 一旦我将应用程序转移到生产环境中,这是不可接受的。

你只需要这样做

  private static void InitializeDataStore() { System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion()); System.Data.Entity.Database.Initialize(false); } 

如果你的应用程序包含Startup.cs类,你可以按如下方式使用DbMigrator类转到你的App_Start文件夹,打开Startup.Auth在ConfigureAuth方法中粘贴这些代码行

 var configuration = new Migrations.Configuration(); var dbmigrator = new DbMigrator(configuration); dbmigrator.Update(); 

注意:请记住使用此命名空间 – 使用System.Data.Entity.Migrations;

这样做的目的是在应用程序启动时随时将数据库更新到最新版本

与Roger相同的解决方案,但在DbContext上使用静态构造函数。 下面的完整代码….这允许初始化代码存在于类本身上,并且在DataDbContext类的第一个实例化时自我调用。

 public partial class DataDbContext : DbContext { public DataDbContext() : base("name=DefaultConnection") { } static DataDbContext() // This is an enhancement to Roger's answer { Database.SetInitializer(new DataDbInitializer()); var configuration = new DataDbConfiguration(); var migrator = new DbMigrator(configuration); if (migrator.GetPendingMigrations().Any()) migrator.Update(); } // DbSet's public DbSet CountryRegion { get; set; } // bla bla bla..... protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove(); modelBuilder.Conventions.Remove(); modelBuilder.Conventions.Remove(); Configuration.ProxyCreationEnabled = false; Configuration.LazyLoadingEnabled = false; //Configuration.ValidateOnSaveEnabled = false; base.OnModelCreating(modelBuilder); modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); // Discover and apply all EntityTypeConfiguration of this assembly, it will discover (*) } } internal sealed class DataDbInitializer : MigrateDatabaseToLatestVersion { } internal sealed class DataDbConfiguration : DbMigrationsConfiguration { public DataDbConfiguration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } protected override void Seed(DataDbContext context) { DataSeedInitializer.Seed(context); base.Seed(context); } } internal static class DataSeedInitializer { public static void Seed(DataDbContext context) { SeedCountryRegion.Seed(context); // bla bla bla..... context.SaveChanges(); } } internal static class SeedCountryRegion { public static void Seed(DataDbContext context) { context.CountryRegion.AddOrUpdate(countryRegion => countryRegion.Id, new CountryRegion { Id = "AF", Name = "Afghanistan" }, new CountryRegion { Id = "AL", Name = "Albania" }, // bla bla bla..... new CountryRegion { Id = "ZW", Name = "Zimbabwe" }); context.SaveChanges(); } } public class CountryRegionConfiguration : EntityTypeConfiguration // (*) Discovered by { public CountryRegionConfiguration() { Property(e => e.Id) .IsRequired() .HasMaxLength(3); Property(e => e.Name) .IsRequired() .HasMaxLength(50); } } public partial class CountryRegion : IEntity { // Primary key public string Id { get; set; } public string Name { get; set; } } public abstract class Entity : IEntity { //Primary key public abstract T Id { get; set; } } public interface IEntity { T Id { get; set; } } 

我们可以看到Seed方法一次又一次地运行。我们可以通过检查迁移是否已经退出来避免这种情况,因为在创建数据库时会自动应用一个..然后我们可以重构DataDbConfiguration,如下所示……

 internal sealed class DataDbConfiguration : DbMigrationsConfiguration { private readonly bool _isInitialized; public DataDbConfiguration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; var migrator = new DbMigrator(this); _isInitialized = migrator.GetDatabaseMigrations().Any(); } protected override void Seed(DataDbContext context) { InitializeDatabase(context); } public void InitializeDatabase(DataDbContext context) { if (!_isInitialized) { if (context.Database.Connection.ConnectionString.Contains("localdb")) { DataSeedInitializer.Seed(context); // Seed Initial Test Data } else { // Do Seed Initial Production Data here } } else { // Do any recurrent Seed here } } }