Entity Framework Code First Migration during deploy to production host does not work

entity-framework entity-framework-6 visual-studio-2013

Question

I am using VS2013 with Entity Framework 6.1 against SQL 2012.

When I use Code First to create my classes and tables in Dev it works fine. When I go to publish via Web Deploy to my third party host everything deploys but none of the tables are created in the DB. The connection string/s contain the appropriate username and password for a user that has table create access to the DB. (Tested because I use the same login/password via SSMS to create tables on the hosted SQL server successfully) The Database publish connection string is being made correctly and has the correct values.

When I deploy the ASP.Net MVC app with the Execute Code First Migrations checkbox marked the app throws a 500 error on the hosted server.

Any thoughts on what might be wrong?

Accepted Answer

For some reason I have to determine there was an EntityFramework section added to the deployed Web.config that was not located in my local version of Web.config. The error was being caused by there being a EntityFramework section but there was no section descriptor specifying that there was an EntityFramework section.

I added the section descriptor and everything works correctly.

I'm not sure why the transform was happening when things were being deployed but the transform was incomplete.


Popular Answer

It sounds like this is a misunderstanding of how the VS Web Deployment feature handles EFCF Migrations.

Normally (non-EFCF), VS publishes your files to the remote server and updates your database schema. By the time the deployment is complete, all changes have been applied.

With EFCF migrations, this is not the case. VS's deployment will modify your web.config to set up the connection strings needed for the database. This is reflected in the published files, but the DB has not been touched at all yet. The changes to the DB don't take place until the migrations code runs. This happens by default the first time your code initializes your DbContext; the DbInitializer will execute any migrations that have not been applied. Generally, this means you have to request a page from your site to trigger this process.

To expound a little bit on my comment:

Manually changing the schema is not a good fix for this, as it will then block the migration from being able to run later ("table Foo already exists" type errors).

If you've made changes to the DB that are incompatible with the Migrations code, you'll get an exception from EF. For example, you might have this migration:

public override void Up()
{
    CreateTable(
        "dbo.Foo",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
                Value = c.String(nullable: false, maxLength: 200),
            })
        .PrimaryKey(t => t.Id);

}

If you've manually created table Foo (e.g. because you didn't see it after deployment), EF can no longer apply this migration, and throws an exception. This can be the cause of the HTTP 500 errors you were seeing.




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