在生产中使用Entity Framework(代码优先)迁移

时间:2012-06-01 10:37:41

标签: .net entity-framework ef-code-first ef-migrations

我只是在为我们的项目使用EF迁移,特别是在发布版本之间执行生产中的模式更改。

我已经看到提到有一个API可以使用DbMigration类在运行时执行这些迁移,但我找不到任何具体的示例。

理想情况下,我希望每个数据库更改一个DbMigration文件,并在应用程序启动时自动应用这些更改从当前版本到最新版本。

5 个答案:

答案 0 :(得分:75)

您可以使用数据库初始化程序在启动时实现向最新版本的迁移(或者更好,dbinitializer将在第一次数据库访问时启动),MigrateDatabaseToLatestVersion,您可以使用它:

Database.SetInitializer<ObjectContext>(
    new MigrateDatabaseToLatestVersion<ObjectContext, Configuration>());

关于每次迁移只有一个文件,如果启用自动迁移,您将在项目根目录的Migrations文件夹中(默认情况下)找到它们。

相关信息,例如:http://weblogs.asp.net/fredriknormen/archive/2012/02/15/using-entity-framework-4-3-database-migration-for-any-project.aspx

答案 1 :(得分:48)

这也有效:

var configuration = new MyDbContextConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
    database.ConnectionString, database.ProviderName);

var migrator = new DbMigrator(configuration);
migrator.Update();

您也可以致电:

migrator.GetPendingMigrations();

获取需要应用的迁移列表。

答案 2 :(得分:6)

由于您没有指定您正在使用的Visual Studio版本或数据库,因此我将在此处添加一个答案,以便在VS2015中使用Microsoft的SQL Server,现在使用“发布”工具非常容易。

您不必费心使用您所说的API。只需在本地完成工作,更改模型,应用迁移等,然后当您想要推出发布/测试服务器时,使用发布工具。

您可以选择在首次启动应用程序时将您在本地进行的任何迁移应用于远程服务器。

完成所有迁移并在本地完成所有操作后(在Dev env中可以推荐)然后发布(右键单击项目,单击“发布...”勾选“执行代码优先迁移(在应用程序启动时运行)” “”设置“标签下的复选框,然后它将在第一次访问应用时应用迁移(因此第一次会有短暂的延迟)。

Publish Web using Web-Deploy

指南: https://msdn.microsoft.com/en-us/library/dd465337(v=vs.110).aspx

我了解了所有这些,因为我必须对Windows 2012服务器执行此操作: http://www.sherweb.com/blog/how-to-install-webdeploy-on-windows-server-2012/

祝你好运!

答案 3 :(得分:2)

我想控制哪些迁移在代码中显式运行,经过大量搜索后我设法开发了以下技术而无需启用DbConfiguration类或自动迁移:

var row = $(this).closest("tr").attr('id');

如果我们有这样的迁移:

public static void RunMigration(this DbContext context, DbMigration migration)
{            
    var prop = migration.GetType().GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
    if (prop != null)
    {
        IEnumerable<MigrationOperation> operations = prop.GetValue(migration) as IEnumerable<MigrationOperation>;
        var generator = new SqlServerMigrationSqlGenerator();
        var statements = generator.Generate(operations, "2008");
        foreach (MigrationStatement item in statements)
            context.Database.ExecuteSqlCommand(item.Sql);
    }
}

我们会这样使用它:

public class CreateIndexOnContactCodeMigration : DbMigration
{
    public override void Up()
    {
        this.CreateIndex("Contacts", "Code");
    }

    public override void Down()
    {
        base.Down();
        this.DropIndex("Contacts", "Code");
    }
}

问候。

答案 4 :(得分:0)

添加到所有已发布的答案中。实体框架使用以下表:dbo .__ MigrationHistory来跟踪已应用于数据库的所有迁移,以避免运行例如以下迁移:插入数据或更改数据库架构。

如果希望运行脚本(例如运行添加数据或更改数据库的模式),则可以使用Package Manager Console创建空迁移,并通过新添加的迁移来运行脚本。确保使用初始化程序来防止EF在每次运行时删除和重新创建数据库。

     public override void Up()
    {
        string directoryToSearchScripts = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\"));

        string scriptFilePath = Directory.GetFiles(directoryToSearchScripts, "dummy-script.sql", SearchOption.AllDirectories).FirstOrDefault();
        if (!string.IsNullOrEmpty(scriptFilePath))
        {
            string fundsSqlScript = File.ReadAllText(scriptFilePath);
            Sql(fundsSqlScript);
        }
    }

    public override void Down()
    {
    }

发布应用程序并选中“执行代码优先迁移”选项时,EF将运行尚未应用于数据库的迁移。