我们首先使用代码EF 4.3.1进行数据库迁移。有时我们删除数据库并让EF重新创建它,主要用于本地开发目的。
有一个过程可以应用挂起的迁移,并且在重新创建数据库时,不需要挂起的迁移,并且当EF尝试应用它们时会引发错误。
我从字符串中检查迁移日期,如果这是在数据库创建日期之前,那么我手动将其添加到__migrationHistory表中,并且不应用迁移。
这涵盖了大多数情况,除非有人重新创建数据库,从源代码控制更新并检索在数据库创建日期之前的未完成迁移。
我还尝试在dbMigrator.Update(migration)方法调用中使用try catch,但是如果一次迁移失败,则不会应用更多的迁移,因为它会记住异常。
有没有人找到解决此问题的方法?
这是我写的方法:
private static void ApplyMigration<T, TU>()
where T : DbContext, new()
where TU : DbMigrationsConfiguration, new()
{
var migrationsAlreadyApplied = new List<string>();
var dbMigrator = new DbMigrator(new TU());
var creationMigrationId = dbMigrator.GetDatabaseMigrations().Single(m => m.Contains("InitialCreate"));
var dbDateCreated = DateTime.ParseExact(creationMigrationId.Substring(0, 12), Constants.MigrationDateFormat, CultureInfo.InvariantCulture);
dbMigrator.GetPendingMigrations().ToList()
.ForEach(migration =>
{
var migrationDate = DateTime.ParseExact(migration.Substring(0, 12), Constants.MigrationDateFormat, CultureInfo.InvariantCulture);
if (migrationDate > dbDateCreated)
dbMigrator.Update(migration);
else
migrationsAlreadyApplied.Add(migration);
});
using (var dbContext = new T())
{
foreach(var migration in migrationsAlreadyApplied)
dbContext.Database.ExecuteSqlCommand("insert into __MigrationHistory "
+ "select '" + migration + "', Model, ProductVersion "
+ "from __MigrationHistory "
+ "where MigrationId = '" + migration + "'");
}
}
答案 0 :(得分:4)
我现在已经解决了这个问题。
在我的dbContext初始化程序的种子方法中,我调用了一个手动填充迁移历史记录的方法。然后,您可以使用ApplyMigrations方法正常调用迁移。
public class UserEntitiesContextInitializer : CreateDatabaseIfNotExists<UserEntitiesContext>
{
protected override void Seed(UserEntitiesContext context)
{
// Update migration history with existing migrations to prevent EF recognising them as pending migrations
DatabaseAdministration.UpdateMigrationHistory<UserEntitiesContext, UserEntitiesContextConfiguration>();
}
}
public static void UpdateMigrationHistory<T, TU>()
where T : DbContext, new()
where TU : DbMigrationsConfiguration, new()
{
using (var dbContext = new T())
{
var dbMigrator = new DbMigrator(new TU());
var creationMigrationId = dbMigrator.GetDatabaseMigrations().Single(m => m.Contains("InitialCreate"));
foreach (var migration in dbMigrator.GetPendingMigrations())
dbContext.Database.ExecuteSqlCommand("insert into __MigrationHistory "
+ "select '" + migration + "', Model, ProductVersion "
+ "from __MigrationHistory "
+ "where MigrationId = '" + creationMigrationId + "'");
}
}
private static void ApplyMigration<T, TU>()
where T : DbContext, new()
where TU : DbMigrationsConfiguration, new()
{
var dbMigrator = new DbMigrator(new TU());
if (dbMigrator.GetPendingMigrations().Any())
dbMigrator.Update(dbMigrator.GetPendingMigrations().Last());
}