Azure + EF 6 - Making code first migrations work


Question

I am using EF 6 (code first with migrations) for MVC 5 project. On my local DEV machine everything works fine.

But when I deploy my project to Azure, I get the following error when my app first tries to interact with the database:

Migrations is enabled for context 'UtilitiesContext' but the database does not exist or
contains no mapped tables. Use Migrations to create the database and its tables, for
example by running the 'Update-Database' command from the Package Manager Console.

I have my EF related code in Utilities.Data assembly and my MVC project is in Utilities.Web assembly.

Here is my code for your reference:

UtilitiesContext.cs

public sealed partial class UtilitiesContext : DbContext
{
    public UtilitiesContext() : base(Settings.Get(Settings.DB_CONNECTION_STRING)) { }

    public DbSet<PreLaunchSubscriber> PreLaunchSubscribers { get; set; }

    private void SetCreatedAtUpdatedAt()
    {
        foreach (DbEntityEntry entityEntry in ChangeTracker.Entries())
        {
            switch (entityEntry.State)
            {
                case EntityState.Added:
                    ((IEntity) entityEntry.Entity).CreatedAt = DateTime.Now;
                    break;
                case EntityState.Modified:
                    ((IEntity) entityEntry.Entity).UpdatedAt = DateTime.Now;
                    break;
            }
        }
    }

    [HandleException]
    public override int SaveChanges()
    {
        SetCreatedAtUpdatedAt();
        return base.SaveChanges();
    }

    [HandleException]
    public override Task<int> SaveChangesAsync()
    {
        SetCreatedAtUpdatedAt();
        return base.SaveChangesAsync();
    }
}

Configuration.cs

internal sealed class Configuration : DbMigrationsConfiguration<UtilitiesContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        ContextKey = "Utilities.Data.Contexts.UtilitiesContext";
    }

    protected override void Seed(UtilitiesContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //
    }
}

Settings.cs

public static class Settings
{
    public const string DB_CONNECTION_STRING = "DB.ConnectionString";

    // other settings ...

    public static string Get([Required] string key)
    {
        return CloudConfigurationManager.GetSetting(key);
    }
}

And I have this defined in the App Settings section for the Configuration tab:

Key: DB.ConnectionString

Value: Data Source=tcp:host.database.windows.net,1433;Initial Catalog=Utilities;User Id=user@server;Password=pwd;

Popular Answer

It looks like the problem you are experiencing is that you deployed your application to Azure, but the database it is trying to target doesn't exist yet.

The best solution for production code is to run the following command from the package manager console on your local machine, this will generate a sql script that you can run against your production database to bring it up to date with your application.

PM> Update-Database -script -sourceMigration 0

Alternatively if you just want to test in azure the MigrateDatabaseToLatestVersion initializer will do what you need and make sure that your database is up to date whenever your app is started. The use of initializers generally is not recommended for production code because altering your production database is something that should be done very carefully.

This blog post is a little old but does a good job outlining both initializers and migrations.





Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why