in EFCore/src/Migrations/Internal/MySQLMigrator.cs [243:318]
public virtual async Task MigrateAsync(
string? targetMigration,
CancellationToken cancellationToken = default)
{
var useTransaction = _connection.CurrentTransaction is null;
if (!useTransaction
&& _executionStrategy.RetriesOnFailure)
{
throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction);
}
if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore
&& HasPendingModelChanges())
{
_logger.PendingModelChangesWarning(_currentContext.Context.GetType());
}
if (!useTransaction)
{
_logger.MigrationsUserTransactionWarning();
}
_logger.MigrateUsingConnection(this, _connection);
using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled);
if (!await _databaseCreator.ExistsAsync(cancellationToken).ConfigureAwait(false))
{
await _databaseCreator.CreateAsync(cancellationToken).ConfigureAwait(false);
}
await _connection.OpenAsync(cancellationToken).ConfigureAwait(false);
try
{
var state = new MigrationExecutionState();
if (_historyRepository.LockReleaseBehavior != LockReleaseBehavior.Transaction
&& useTransaction)
{
state.DatabaseLock = await _historyRepository.AcquireDatabaseLockAsync(cancellationToken).ConfigureAwait(false);
}
await _executionStrategy.ExecuteAsync(
this,
static async (_, migrator, ct) =>
{
await migrator._connection.OpenAsync(ct).ConfigureAwait(false);
try
{
return await migrator._historyRepository.CreateIfNotExistsAsync(ct).ConfigureAwait(false);
}
finally
{
await migrator._connection.CloseAsync().ConfigureAwait(false);
}
},
verifySucceeded: null,
cancellationToken).ConfigureAwait(false);
await _executionStrategy.ExecuteAsync(
(Migrator: this,
TargetMigration: targetMigration,
State: state,
UseTransaction: useTransaction),
async static (c, s, ct) => await s.Migrator.MigrateImplementationAsync(
c, s.TargetMigration, s.State, s.UseTransaction, ct).ConfigureAwait(false),
async static (_, s, ct) => new ExecutionResult<bool>(
successful: await s.Migrator.VerifyMigrationSucceededAsync(s.TargetMigration, s.State, ct).ConfigureAwait(false),
result: true),
cancellationToken)
.ConfigureAwait(false);
}
finally
{
await _connection.CloseAsync().ConfigureAwait(false);
}
}