实体框架 4.3 在应用程序启动时运行迁移

34

如何在应用程序启动时使用 EF 4.3 执行所有必需的数据库迁移是最佳方法?


2
你的意思是通过代码运行吗?那么,这里有一个链接供你参考http://romiller.com/2012/02/09/running-scripting-migrations-from-code/。 - J.W.
3个回答

54

最好的方法应该是使用新的 MigrateDatabaseToLatestVersion 初始化器。

Database.SetInitializer<YourContext>(
    new MigrateDatabaseToLatestVersion<YourContext, YourMigrationsConfig>());
Database.Initialize(false);

4
这段代码应该放在哪里?由于Database.Initialize不能在静态环境中使用,因此无法在App_Start中使用它。 - Maxim V. Pavlov
4
它会立即执行数据库初始化。如果你不使用它,则初始化将发生在你的应用程序首次尝试访问数据库时。 - Ladislav Mrnka
3
在 EF 6.1 中,Initialize() 不是一个静态方法。 - Eric J.
@Eric J 有其他的选择吗? - Ammar Khan
@user3398887:你需要拥有一个数据库实例(例如从已实例化的上下文中获取)。 - Eric J.
显示剩余3条评论

6
你可以在ADO.NET团队博客的EF 4.3配置文件设置中找到有关EF 4.3配置选项的详细描述。最后一节介绍了数据库初始化器,包括新的Code First MigrateDatabaseToLatestVersion初始化器。
尽管Entity Framework - 像.NET 4.x的许多其他功能一样 - 更喜欢约定优于配置,但在这种情况下,通过应用程序的配置文件设置MigrateDatabaseToLatestVersion数据库初始化器可能非常有用,而不是将其明确地编码到应用程序中。

在使用配置时,还要注意我的评论,以使配置更易读。 - Rudi

4
我需要明确地执行此操作,因为我在迁移时使用了一个超级上下文,它是其他迁移的超集。关键部分如下:
var dbMigrator = new System.Data.Entity.Migrations.DbMigrator(
    new Lcmp.EF.Migrations.Migrations.Configuration());
dbMigrator.Update();

在使用 Elmah 日志记录的情况下,我实际上使用此代码,从 Application_Start() 调用它。其中一些部分是从其他人的想法中借鉴而来的。我不能确定线程安全的 Interlocked 部分是否必要。

public static int IsMigrating = 0;
private static void UpdateDatabase()
{
    try
    {
        if (0 == System.Threading.Interlocked.Exchange(ref IsMigrating, 1))
        {
            try
            {
                // Automatically migrate database to catch up.
                Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Checking db for pending migrations.")));
                var dbMigrator = new System.Data.Entity.Migrations.DbMigrator(new Lcmp.EF.Migrations.Migrations.Configuration());
                var pendingMigrations = string.Join(", ", dbMigrator.GetPendingMigrations().ToArray());
                Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("The database needs these code updates: " + pendingMigrations)));
                dbMigrator.Update();
                Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Done upgrading database.")));
            }
            finally
            {
                System.Threading.Interlocked.Exchange(ref IsMigrating, 0);
            }
        }
    }
    catch (System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException ex)
    {  
        Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
    }
    catch (Exception ex)
    {
        Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接