0

我最近从 EF6 alpha 1-3 升级到 EF6 beta 1。意味着我必须重新创建使用 alpha 版本创建的所有迁移。

所以我尝试回滚到使用 EF5 创建的迁移。但是我遇到了错误Introducing FOREIGN KEY constraint on table 可能会导致循环或多个级联路径。我认为这是因为当我为完全相同的问题修复 Up 迁移时,我忽略了修复 Down 迁移。(应该以前读过这个

无论如何,我没有尝试全部修复,而是尝试重置所有迁移 - 如此所述。我删除了数据库中的迁移表和所有迁移 .cs 文件,然后在包管理器Enable-Migrations -EnableAutomaticMigrations -ForceAdd-Migration Initial

当我尝试使用现有的数据库初始化程序(自动迁移错误)运行我的应用程序时,它失败了,因为它试图创建已经存在的表。所以我将初始化程序更改为Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>())

这次我得到了Introducing FOREIGN KEY constraint on table 可能会在初始化期间再次导致循环或多级联路径问题

所以我将迁移文件中的所有更改cascadeDelete: truecascadeDelete: false

但我仍然得到同样的错误!

更新 1我删除了迁移文件中除了创建 1 个表之外的所有内容,但我得到了同样的错误。某处一定有某种缓存,或者它正在拾取我不知道的文件,或者它正在后台生成自己的迁移

更新 2我认为在使用DropCreateDatabaseAlways该 EF 时必须始终生成迁移,并且cascadeDelete在迁移文件中更改为 false 是错误的地方。它应该在 FluentAPI 中完成。所以我将这一行添加modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();到 onmodelcreating 中。而且我还删除了初始迁移文件。然后我运行了应用程序,它正确地生成了一个数据库。我以为我已经破解了它,但是......

我更改了初始化以使用我的原始配置文件:

internal sealed class Configuration : DbMigrationsConfiguration<SID2013Context>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            AutomaticMigrationDataLossAllowed = true;
        }

         protected override void Seed(etc..
}

然后我运行应用程序,它报告模型已更改。所以我做了 Add-Migration Update-Database 并创建了一个用于创建数据库的迁移文件。

现在的问题是,当我运行应用程序时,它会尝试运行另一个更新(即使 AutomaticMigrationsEnabled = false)。我再次得到“数据库中已经有一个名为'xxx'的对象”问题。迁移表中有一个条目与配置文件的名称不匹配。

4

2 回答 2

2

如果您想使用现有数据库开始“代码优先迁移”工作,您可以执行以下操作:

  1. 我运行添加迁移“InitialMigrations”。
  2. 它探索现有数据库并将其作为迁移步骤。
  3. 暂时删除“InitialMigrations”步骤的内容:

    public partial class InitialMigrations : DbMigration {
        public override void Up()
        {
            //...
            //...
        }
    
        public override void Down()
        {
            //...
            //...
        } 
    }
    
  4. 我运行更新数据库

  5. 这将在表 __MigrationHistory 中创建适当的条目。
  6. 恢复“InitialMigration”的内容,以便在空数据库上正常工作。

而已。

更新:初始化程序

据我了解,“DropCreateDatabaseAlways”总是删除和创建数据库。这只能用于第一次安装。如果您有一个正常工作的安装启动板,则会删除所有数据。这就是我危险的原因。

我基于这篇文章:coding.abel.nu/2012/03/...我自己的初始化器我正在使用。我会写。

种子肯定会执行,因此此方法产生相同的结果,但即使您不运行安装,而是运行升级,它也可以工作。

public partial class MyEntities : DbContext
{
   static MyEntities()
   { 
       Database.SetInitializer<MyEntities>(new ValidateDatabase<MyEntities>());
   }
}
/// <summary>
/// http://coding.abel.nu/2012/03/prevent-ef-migrations-from-creating-or-changing-the-database/
/// </summary>
/// <typeparam name="TContext"></typeparam>
public class ValidateDatabase<TContext> : IDatabaseInitializer<TContext>
  where TContext : DbContext
{
    public void InitializeDatabase(TContext context)
    {
        if (!context.Database.Exists())
        {
            throw new ConfigurationErrorsException(
              "Database does not exist");
        }
        else
        {
            if (!context.Database.CompatibleWithModel(true))
            {
                //from:
                //http://stackoverflow.com/questions/11611322/ef-4-3-code-first-migrations-seed-per-migration
                var cfg = new Migrations.Configuration();
                var migrator = new DbMigrator(cfg);

                ///Last in the db, (first, the reverse order)
                var dbLast = migrator.GetDatabaseMigrations().FirstOrDefault();
                ///last in the app
                var appLast = migrator.GetLocalMigrations().LastOrDefault();
                ///what is missing
                var pendings = string.Join(", ", migrator.GetPendingMigrations());
                throw new InvalidOperationException(
                  string.Format("The database ({0}) is not compatible with the entity model ({1}). Pending migrations: {2}",
                    dbLast, appLast, pendings));
            }
        }
    }
}

更新:设置

安装我正在使用这样的东西:

http://coding.abel.nu/2012/04/update-database-msi-custom-action/

于 2013-07-19T09:00:33.510 回答
0

我最终通过手动删除数据库然后使用原始MigrateDatabaseToLatestVersion初始化程序运行应用程序来解决此问题。我没有意识到如果数据库不存在并且不需要使用DropCreateDatabaseAlways初始化程序然后更改为MigrateDatabaseToLatestVersion

于 2013-08-09T09:45:29.350 回答