How do I generate an EF6 database with migrations enabled, without using update-database?

entity-framework

Question

In EF5, I relied on the fact that I could recreate my database from the model using Database.CreateIfNotExists()

I would generate Migrations as needed, but never check them in to source control (since they tended to be artifacts of the development cycle) Each developer would then delete and recreate their own databases, from the model as needed.

Then, we would generate migrations by comparing branches of our code, and get the SQL, to apply to production or other shared databases.

This workflow no longer seems to work, as there is no way to generate a database from scratch when migrations are enabled, without first generating all the migrations and then calling update-database. Since calling add-migration modifies the csproj file, this makes my scripts (which allow us to easily switch branches) unusable.

Migrations is enabled for context 'ApplicationDbContext' 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.

Is there any way to revert to EF5 behavior where Database.Create will create the current version of the db?

1
12
10/21/2013 10:36:11 AM

Popular Answer

I was using CreateDatabaseIfNotExists to initialize the DB and was able to use update-database and run my application and it would create the DB if it didn't already exist. This seems to have broken with EF 6.0.x.

This was useful, but not what I used.

What I did was abandon my existing initialize code and replaced it with the following code in Global.asax.

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
        using (MyContext temp = new MyContext())
        {
            temp.Database.Initialize(true);
        }

Note: MyContext is the context I use and Configuration is the Configuration file that is created when migrations are enabled.

I have seen a lot of posts where people are having problems about this, but not many that describe a solution. I'm not sure why so many people, including myself, have missed this breaking change... (If there's a description about this somewhere, I never saw it until it was too late.)

Edit:

This is code that I added to my context class. I don't like it as much as how it used to work, but it gets the job done for now. See @Doug's comment to the OP about voting on CodePlex.

private static readonly Object syncObj = new Object();
public static bool InitializeDatabase()
{
    lock (syncObj)
    {
        using (var temp = new TbdContext())
        {
            ObjectContext oc = null;
            try
            {
                oc = temp.ObjectContext;
            }
            catch (Exception ex)
            {
                //Ignore error
                Console.WriteLine(ex);
            }

            if (oc != null && oc.DatabaseExists())
            {
                return true;
            }
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<TbdContext, Configuration>());
            try
            {
                temp.Database.Initialize(true);
                return true;
            }
            catch (DataException ex)
            {

        }
    }
}

Then in my Global.asax.cs Application_Start() I do this:

if (databaseInitialized == false)
    databaseInitialized = MyContext.InitializeDatabase();

Edit:

I upgraded to EF 6.1 and found this doesn't work anymore.(https://stackoverflow.com/a/22770517/2033294) Here's what I did to fix it:

    private static readonly Object syncObj = new Object();
    public static bool InitializeDatabase()
    {
        lock (syncObj)
        {
            using (var temp = new MyContext())
            {
                if (temp.Database.Exists()) return true;

                var initializer = new MigrateDatabaseToLatestVersion<MyContext, Configuration>();
                Database.SetInitializer(initializer);
                try
                {
                    temp.Database.Initialize(true);
                    return true;
                }
                catch (Exception ex)
                {
                    //Handle Error in some way
                    return false;
                }
            }
        }
    }
12
5/23/2017 12:02:02 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow