Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure Web App migrations #3597

Closed
bragma opened this issue Oct 29, 2015 · 8 comments
Closed

Azure Web App migrations #3597

bragma opened this issue Oct 29, 2015 · 8 comments

Comments

@bragma
Copy link

bragma commented Oct 29, 2015

Hello,
I've checked the docs but found nothing regarding the best practice for handling EF7 migrations on Azure Web App projects and I'm not sure on how to proceed. I'd like migrations to be checked and applied on publishing. Have I missed anything or are they scheduled for later release?
Thanks for any suggestion.

@skrim
Copy link

skrim commented Oct 29, 2015

It may be more straightforward to have the application check and apply the migrations, rather than the publish process. This can be done, for example, by adding the following to your app startup sequence, after configuration of EF has been done.

using(var dbContext = new YourDbContext()) {
    dbContext.Database.Migrate();
}

This will check the db level using __EFMigrationHistory table and run missing increments. The migration seems to run in a transaction, so starting multiple server instances at the same time should be fine.

To do this right after build, this command in the build script can be used to wake the application after publishing.

Invoke-RestMethod http://WEBSITENAME.azurewebsites.net -TimeOutSec 120

@bragma
Copy link
Author

bragma commented Oct 29, 2015

ADDENDA to what I wrote below: it seems that "Database.Migrate" already creates the database if it does not exist, so the call to:

    context.Database.Migrate();

Is enough. Thanks a lot!
END OF ADDENDA

Thanks, I'll follow suggestion #1. I'm trying to call this from my ASP.NET vNext Startup.Configure() method:

if (!context.Database.EnsureCreated())
{
    context.Database.Migrate();
}

It seems that the "EnsureCreated" does create the DB and it's schema, but it does not create the "EFMigrationsHistory" table.
On next start of the app, the "Migrate" method is called, which instead tries to ally all migrations (since there is no history table and fails because Tables already exist.
I'm wondering if there is a method to create the DB and let migrations build the schema.

@divega
Copy link
Contributor

divega commented Oct 29, 2015

EnsureCreated() is just a quick way to create the database, mostly useful in testing, and should not be mixed with migrations. You can just use context.Database.Migrate() and if you are going to do it from Startup.Configure() you should also wrap it into a DI scope to make sure the right services will be created with the right lifetime, e.g.:

using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
{ 
    using(var context = scope.ServiceProvider.GetService<MyContext>())
    { 
        context.Database.Migrate();
    }
} 

Note that applying migrations at runtime is not in generally a good idea. E.g. if you have more than one Web server, this could cause multiple servers to try to update the database at the same time which will most likely cause errors and leave the database in a bad state.

To the original question, we are still working in the publish story. @sayedihashimi may be able to offer more details and the timeframe.

cc @rowanmiller

@rowanmiller
Copy link
Contributor

Here is a slightly outdated doc that walks thru what we are building in terms of publish integration https://github.com/aspnet/EntityFramework/wiki/Visual-Studio-Publish-Integration. There are some minor technical details that are incorrect but the general flow is correct.

@sayedihashimi
Copy link
Member

Yes we are working on adding support for EF Migrations into the publish dialog now. I do not think this will make it for RC1 but should for the release after that.

I just posted the spec on what we are working on at aspnet/Tooling#251. We should have the script working in a few weeks. When that happens if anyone wants to try it (without UI support) then I can describe the elements that need to be updated to get the migrations to be invoked.

@bragma
Copy link
Author

bragma commented Oct 30, 2015

Thanks to everybody for the useful insight.

@divega regarding applying migrations at runtime, what about a command line tool that executes "Database.Migrate()"?

Regarding the DI scope, is it wrong to get a context in this way?

public void ConfigureServices(IServiceCollection services)
{
...
    // Add Entity Framework services to the services container.
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext context)
{
...
    context.Database.Migrate();
...
}

@divega
Copy link
Contributor

divega commented Oct 30, 2015

The main issue with running code directly in Startup.Configure() is that any services (including the DbContext itself) that are registered as scoped will not be instantiated with the right lifetime. There are some more details at #3070 (comment) and a discussion on how we can potentially make that easier at https://github.com/aspnet/Hosting/issues/373.

@bragma
Copy link
Author

bragma commented Nov 2, 2015

@divega Thanks for the details.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants