I implemented database migrations in my ASP.NET core solution as it's recommended in the following issue: Pattern for seeding database with EF7 in ASP.NET 5
My solution is setup for working on linux docker and the application depends on a MySql container that is configured in the docker compose file and setup on the first run.
The migrations run in the Startup.Configure method as:
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
context.Database.Migrate();
context.EnsureSeedData();
}
But running the application for the first time always throws the following error:
An exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in System.Private.CoreLib.ni.dll but was not handled in user code
Then if I wait some seconds and re-launch the debug session the code executes without problem and the first-run data is there.
Is there a way that it could wait for the DB server to be ready before running the migrations?
EDIT:
If I change the migration method for the one in this question: Cannot get the UserManager class instead of the previous error I get this one:
An exception of type 'System.AggregateException' occurred in System.Private.CoreLib.ni.dll but was not handled in user code
Is there a way that it could wait for the DB server to be ready before running the migrations?
In your Program.Main, you could add code that attempts to open a connection to MySql, and loop until the connection opens successfully.
For example:
public static void Main()
{
MySqlConnection connection;
while (true)
{
try
{
connection = new MySqlConnection("Database=mysql; Server=server;User ID=user;Password=password");
connection.Open();
break;
}
// ex.Number = 1042 when the server isn't up yet, assuming you're using MySql.Data and not some other MySql implementation
catch (MySqlException ex) when (ex.Number is 1042)
{
Console.Error.WriteLine("Waiting for db.");
Thread.Sleep(1000);
}
}
// ... continue launching website
}