Using Entity Framework (code first) migrations in production

一曲冷凌霜 提交于 2019-11-26 14:53:33
WDRust

There is a Database Initializer you can use to achieve the migration to latest version on startup (or better, the dbinitializer will kick in on first db access), the MigrateDatabaseToLatestVersion, you use it like that:

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

Regarding having one file per migration, if you enable automatic migrations you will find them in the Migrations folder (by default) in the root of your project.

Relevant info, with examples, here: http://weblogs.asp.net/fredriknormen/archive/2012/02/15/using-entity-framework-4-3-database-migration-for-any-project.aspx

mackie

This works too:

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

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

You can also call:

migrator.GetPendingMigrations();

to get a list of the migrations it needs to apply.

Since you didn't specify which Visual Studio version you are using, or Database, I will add an answer here to say that in VS2015 with Microsoft's SQL Server, this is now incredibly easy using the "Publish" tool.

You do not need to bother with the API you speak of. Simply do your work locally, changing your models, applying migrations etc, then when you want to push out to release/test servers, use the publish tool.

You can select to apply any migrations you have made locally, to the remote server the first time the application is started up.

Once you have all of your migrations and everything done locally (presumable in your Dev env) then you publish (right click the project, click "Publish..." Tick the "Execute Code First Migrations (runs on application startup)" checkbox under the "Settings" tab and then it will apply the migrations the first time the app is accessed (so there will be a short delay the first time).

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

I learned all this because I had to do this to a Windows 2012 server: http://www.sherweb.com/blog/how-to-install-webdeploy-on-windows-server-2012/

Good luck!

I wanted to control which migrations run explicitly in code and after a lot of search i managed to develop the following technique without the need of a DbConfiguration class or automatic migrations enabled:

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);
    }
}

And if we had a migration like this:

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

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

We would use it like that:

using (var dbCrm = new CrmDbContext(connectionString))
{
    var migration = new CreateIndexOnContactCodeMigration();
    migration.Up();                
    dbCrm.RunMigration(migration);
}

Regards.

To add to all the answers already posted. Entity Framework uses a table: dbo.__MigrationHistory to keep track of all the migrations that have already been applied to the database to avoid running a migration that for example: inserts data or changes the database schema.

If you wish to run a script such as run adding data or changing the schema of the database you can create an empty migration using Package Manager Console and run the script via the the newly added migration. Ensure you use the initializer is used to prevent EF from dropping and recreating the database on every run.

     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()
    {
    }

When you publish the application and check the "Execute Code First Migrations" option, EF will run the migrations that have not yet been applied to the database.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!