我最近从EF6 alpha 1-3升级到EF6 beta 1. This意味着我必须重新创建使用alpha版本创建的所有迁移。
所以我尝试回滚到使用EF5创建的迁移。但我点击错误在表上引入FOREIGN KEY约束可能会导致循环或多个级联路径。我认为这是因为当我修复完全相同问题的迁移时,我忽略了修复Down迁移。 (之前应该阅读this)
无论如何,我试图重置所有迁移,而不是尝试修复它 - 如here所述。我删除了数据库中的迁移表和所有迁移.cs文件,然后是包管理器Enable-Migrations -EnableAutomaticMigrations -Force
和Add-Migration Initial
当我尝试使用现有的数据库初始化程序(自动迁移为false)运行我的应用程序时,它失败了,因为它试图创建已存在的表。所以我将初始化程序更改为Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>())
这次我在表上引入了引入FOREIGN KEY约束可能会在初始化期间再次导致循环或多个级联路径问题
所以我在迁移文件中将所有cascadeDelete: true
更改为cascadeDelete: 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'的对象”问题了。迁移表中有一个与配置文件名称不匹配的条目。
答案 0 :(得分:2)
如果您想使用现有数据库开始“代码优先迁移”工作,您可以执行以下操作:
暂时删除“InitialMigrations”步骤的内容:
public partial class InitialMigrations : DbMigration {
public override void Up()
{
//...
//...
}
public override void Down()
{
//...
//...
}
}
我运行update-database
就是这样。
更新:初始化程序
据我了解,'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/
答案 1 :(得分:0)
我最后通过手动删除数据库然后使用原始MigrateDatabaseToLatestVersion
初始化程序运行应用程序来解决此问题。我没有意识到这会创建数据库,如果它不存在,并且不需要使用DropCreateDatabaseAlways
初始化程序然后更改为MigrateDatabaseToLatestVersion