EF Core Automated Migration Flow

Viewed 148

So what I am trying to do, is to build a kinda automated flow of migrations for the development environment, as mentioned in the title. I don't like the principle, that you have to execute dotnet ef migrations add <migration> every time you have some changes, that you need on your database, and I am building a huge project with a few mates, so I need that. I hope someone can help me here.

Steps of how it is supposed to work

  1. Start running or rerunning the project
  2. The user will be prompted in the terminal, to enter within 3 seconds 'y'or 'n' for adding a new migration (if no was chosen, or the timeout was reached, the project will just start normally)
  3. The user entered 'y', he will be prompted to enter a migration name
  4. A migration file will be generated using ef core
  5. The project applies the new generated migration to the database

How it is currently working

  1. Step 1 to 4 are operational, and I am satisfied with that
  2. Step 5 is not applying the migration to the database on the same project startup as mentioned in the steps above, to apply the migrations, I have to actually give the project a second restart/rerun, so it applies it.

Relevant code snippets:

At Startup.cs, I have the following tasks in the following order:

These tasks where implemented, according to this article

if (_env.IsDevelopment()) 
            services.AddStartupTask<MigrationWizardStartupTask>();
        services.AddStartupTask<MigrationStartupTask>();

The MigrationWizardStartupTask contains the following relevant part:

                do
                {
                    Console.WriteLine("\nMigration or change name (camel case, no spaces input): ");
                    migrationName = Console.ReadLine();
                    if (migrationName?.TrimEmptyToNull() == null || migrationName.Split(" ").Length > 1)
                    {
                        _restartWizard = true;
                        Console.WriteLine(
                            "Incorrect input, please enter the name with no spaces and try again....");
                    }
                    else
                    {
                        _restartWizard = false;
                    }
                } while (_restartWizard);

                _logger.LogInformation("Creating migration....");

                var migrationTask = new Task(() =>
                    {
                        Tercmd.DotnetBuilder.Create(baseDir.MigrationsPathFromRoot())
                            .AddMigration(migrationName, 5000);
                    });
                migrationTask.Start();
                migrationTask.Wait();

and the AddMigration method basically executes the command with a thread sleep:

               var proc = new Process
                {
                    StartInfo =
                    {
                        WorkingDirectory = _directory, FileName = TerminalKeys.Dotnet.ToLowerString(),
                        Arguments = $"ef migrations add {migrationName}",
                        CreateNoWindow = false
                    }
                };
                proc.Start();
                proc.WaitForExit();
                Thread.Sleep(sleepTime);

The second task is the MigrationStartupTask which should always run, and basically only migrates the database.

                _logger.LogInformation("Initializing Db connection....");
                var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
                var pendingMigrations = await db.Database.GetPendingMigrationsAsync();
                var pendingMigrationsCount = pendingMigrations.Count();
                _logger.LogInformation("Starting Migrations, migrations pending: {0}", pendingMigrationsCount);
                await db.Database.MigrateAsync();

So it seems that it is probably already migrating the database, without having the generated file ready. That is my thought, but I can't figure out where the problem is, and how to fix it.

Thanks in advance!!

0 Answers
Related