|
3 | 3 |
|
4 | 4 | using System.Transactions;
|
5 | 5 | using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
|
| 6 | +using Microsoft.EntityFrameworkCore.Metadata.Internal; |
6 | 7 |
|
7 | 8 | namespace Microsoft.EntityFrameworkCore.Migrations.Internal;
|
8 | 9 |
|
@@ -93,24 +94,7 @@ public Migrator(
|
93 | 94 | public virtual void Migrate(string? targetMigration)
|
94 | 95 | {
|
95 | 96 | var useTransaction = _connection.CurrentTransaction is null;
|
96 |
| - if (!useTransaction |
97 |
| - && _executionStrategy.RetriesOnFailure) |
98 |
| - { |
99 |
| - throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); |
100 |
| - } |
101 |
| - |
102 |
| - if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore |
103 |
| - && HasPendingModelChanges()) |
104 |
| - { |
105 |
| - _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); |
106 |
| - } |
107 |
| - |
108 |
| - if (!useTransaction) |
109 |
| - { |
110 |
| - _logger.MigrationsUserTransactionWarning(); |
111 |
| - } |
112 |
| - |
113 |
| - _logger.MigrateUsingConnection(this, _connection); |
| 97 | + ValidateMigrations(useTransaction); |
114 | 98 |
|
115 | 99 | using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled);
|
116 | 100 |
|
@@ -235,24 +219,7 @@ public virtual async Task MigrateAsync(
|
235 | 219 | CancellationToken cancellationToken = default)
|
236 | 220 | {
|
237 | 221 | var useTransaction = _connection.CurrentTransaction is null;
|
238 |
| - if (!useTransaction |
239 |
| - && _executionStrategy.RetriesOnFailure) |
240 |
| - { |
241 |
| - throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); |
242 |
| - } |
243 |
| - |
244 |
| - if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore |
245 |
| - && HasPendingModelChanges()) |
246 |
| - { |
247 |
| - _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); |
248 |
| - } |
249 |
| - |
250 |
| - if (!useTransaction) |
251 |
| - { |
252 |
| - _logger.MigrationsUserTransactionWarning(); |
253 |
| - } |
254 |
| - |
255 |
| - _logger.MigrateUsingConnection(this, _connection); |
| 222 | + ValidateMigrations(useTransaction); |
256 | 223 |
|
257 | 224 | using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled);
|
258 | 225 |
|
@@ -382,6 +349,48 @@ await _migrationCommandExecutor.ExecuteNonQueryAsync(
|
382 | 349 | }
|
383 | 350 | }
|
384 | 351 |
|
| 352 | + private void ValidateMigrations(bool useTransaction) |
| 353 | + { |
| 354 | + if (!useTransaction |
| 355 | + && _executionStrategy.RetriesOnFailure) |
| 356 | + { |
| 357 | + throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); |
| 358 | + } |
| 359 | + |
| 360 | + if (_migrationsAssembly.Migrations.Count == 0) |
| 361 | + { |
| 362 | + _logger.MigrationsNotFound(this, _migrationsAssembly); |
| 363 | + } |
| 364 | + else if (_migrationsAssembly.ModelSnapshot == null) |
| 365 | + { |
| 366 | + _logger.ModelSnapshotNotFound(this, _migrationsAssembly); |
| 367 | + } |
| 368 | + else if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore |
| 369 | + && HasPendingModelChanges()) |
| 370 | + { |
| 371 | + var modelSource = (ModelSource)_currentContext.Context.GetService<IModelSource>(); |
| 372 | +#pragma warning disable EF1001 // Internal EF Core API usage. |
| 373 | + var newDesignTimeModel = modelSource.CreateModel( |
| 374 | + _currentContext.Context, _currentContext.Context.GetService<ModelCreationDependencies>(), designTime: true); |
| 375 | +#pragma warning restore EF1001 // Internal EF Core API usage. |
| 376 | + if (_migrationsModelDiffer.HasDifferences(newDesignTimeModel.GetRelationalModel(), _designTimeModel.Model.GetRelationalModel())) |
| 377 | + { |
| 378 | + _logger.NonDeterministicModel(_currentContext.Context.GetType()); |
| 379 | + } |
| 380 | + else |
| 381 | + { |
| 382 | + _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); |
| 383 | + } |
| 384 | + } |
| 385 | + |
| 386 | + if (!useTransaction) |
| 387 | + { |
| 388 | + _logger.MigrationsUserTransactionWarning(); |
| 389 | + } |
| 390 | + |
| 391 | + _logger.MigrateUsingConnection(this, _connection); |
| 392 | + } |
| 393 | + |
385 | 394 | private IEnumerable<(string, Func<IReadOnlyList<MigrationCommand>>)> GetMigrationCommandLists(MigratorData parameters)
|
386 | 395 | {
|
387 | 396 | var migrationsToApply = parameters.AppliedMigrations;
|
@@ -449,10 +458,6 @@ protected virtual void PopulateMigrations(
|
449 | 458 | var appliedMigrations = new Dictionary<string, TypeInfo>();
|
450 | 459 | var unappliedMigrations = new Dictionary<string, TypeInfo>();
|
451 | 460 | var appliedMigrationEntrySet = new HashSet<string>(appliedMigrationEntries, StringComparer.OrdinalIgnoreCase);
|
452 |
| - if (_migrationsAssembly.Migrations.Count == 0) |
453 |
| - { |
454 |
| - _logger.MigrationsNotFound(this, _migrationsAssembly); |
455 |
| - } |
456 | 461 |
|
457 | 462 | foreach (var (key, typeInfo) in _migrationsAssembly.Migrations)
|
458 | 463 | {
|
|
0 commit comments