Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Database.Migrate() creating database but not tables, EF & .NET Core 2

This question has been asked a couple times but none of the solutions/documentation is working for me.

Scenario - I need to build a database from scratch and edit it with migrations all from code, according to the documentation the line below should create the database from the DbContext/ModelBuilder.

_dbContext.Database.Migrate();

however this is only creating the database itself and none of the tables. If I run the below instead,

_dbContext.Database.EnsureCreated();

the database AND all the tables are created however this is not an option as I need to edit with migrations further down the line. I've tried the code below directly after the Migrate line but pendingMigrations is always 0.

var pendingMigrations = _dbContext.Database.GetAppliedMigrations().ToList();
        if (pendingMigrations.Any())
        {
            var migrator = _dbContext.Database.GetService<IMigrator>();
            foreach (var targetMigration in pendingMigrations)
                migrator.Migrate(targetMigration);
        }

Is there something I'm missing here? Shouldn't Database.Migrate() be creating the tables as well as the database?

Note - in testing I am deleting the database before trying another approach.

like image 902
James Morrison Avatar asked May 24 '18 11:05

James Morrison


2 Answers

Another classic case of struggling with something for a day or two only to find the answer half an hour after posting a question here. Posting my solution incase other people have had a similar issue.

TLDR - _dbContext.Database.Migrate(); doesn't create migrations.

Basically, dbContext.Database.EnsureCreated() doesn't care about migrations, which is why it generated the full database inc tables (however then of course you can't migrate).

_dbContext.Database.Migrate(); applies the migrations and creates the database if it doesn't exist however it doesn't create the tables if there's no migration.

Basically I have a project as a resource, I was trying to duplicate the project from a new application generated by the user but as I'd never run any migrations in the resource project there was nothing to migrate. Running the Add-Migration Initial in the PMC in the resource project gave the project it's initial migration files so then when I ran migrate on a new database it knew which tables to create.

like image 192
James Morrison Avatar answered Jan 04 '23 11:01

James Morrison


In my case I had multiple projects and DesignTimeDbContextFactory was pointing to a MigrationsAssembly but in startup sqlOptions were not.

enter image description here enter image description here

so when DI creates DbContext it does't know there are pending migrations.

you can check you pending migrations with dbContext.Database.GetPendingMigrations(); before Migrate(); to check if it has found migrations or not

Solution is add migration MigrationsAssembly in sqlOptions

 services.AddDbContext<BM_OCR_DbContext>(options =>
                {
                    options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection"),
                    sqlServer => sqlServer.MigrationsAssembly("BM.OCR.Server"));
                });
like image 33
hanan Avatar answered Jan 04 '23 10:01

hanan