/// <summary> /// Determines and applies migrations to the target system. This is done by getting the /// latest applied migration info from the target system, picking the migrations /// that must be executed, and applying them to the target system. /// PLEASE NOTE: when migrations are applied, all exceptions are caught by the migration engine. /// Exceptions are not caught in the analysis phase beforehand (when the latest migration info is retrieved). /// This means that you must analyze the summary for errors (e.g. via <see cref="MigrationSummary{TMigrationInfo}.EnsureSuccess" />) /// to ensure that no errors occurred during a run. /// </summary> /// <param name="now"> /// The current time when the migration engine starts to execute (optional). Please use a UTC time stamp if possible. If /// you do not provide a value, <see cref="DateTime.UtcNow" /> will be used. /// </param> /// <param name="assembliesContainingMigrations"> /// The assemblies that will be searched for migration types (optional). If you do not provide any assemblies, /// the calling assembly will be searched. /// </param> /// <param name="approach"> /// The approach that should be taken to apply migrations (optional). The default is to determine the latest migration version /// of the target system and then apply all newer migrations. See the <see cref="MigrationApproach" /> enum for detailed infos. /// </param> /// <param name="cancellationToken">The token to cancel this asynchronous operation (optional).</param> /// <returns>A summary of all migrations that have been applied in this run and an optional error that might have occurred during a migration.</returns> /// <exception cref="MigrationException">Thrown when the migration infos in your target system are invalid, or when there are several migrations with the same version.</exception> /// <exception cref="Exception">A system-specific exception might occur when there are errors with the connection to the target system (e.g. a SqlException).</exception> public virtual Task <MigrationSummary <TMigrationInfo> > MigrateAsync(DateTime?now = null, Assembly[]?assembliesContainingMigrations = null, MigrationApproach approach = MigrationApproach.MigrationsWithNewerVersions, CancellationToken cancellationToken = default) { if (assembliesContainingMigrations.IsNullOrEmpty()) { assembliesContainingMigrations = new[] { Assembly.GetCallingAssembly() } } ; return(MigrateInternalAsync(now, assembliesContainingMigrations, approach, cancellationToken)); // ReSharper disable VariableHidesOuterVariable async Task <MigrationSummary <TMigrationInfo> > MigrateInternalAsync(DateTime?now, Assembly[] assembliesContainingMigrations, MigrationApproach approach, CancellationToken cancellationToken) // ReSharper restore VariableHidesOuterVariable { var migrationPlan = approach == MigrationApproach.AllNonAppliedMigrations ? await GetPlanForNonAppliedMigrationsInternal(assembliesContainingMigrations, cancellationToken) : await GetPlanForNewMigrationsInternal(assembliesContainingMigrations, cancellationToken); return(await ApplyMigrationsAsync(migrationPlan.PendingMigrations, now, cancellationToken)); } }
public static async Task <MigrationSummary <MigrationInfo> > ApplyMigrationsFromTestClass <T>( this MigrationEngine <DatabaseContext> migrationEngine, MigrationApproach approach = MigrationApproach.MigrationsWithNewerVersions) { var testMigrations = new List <PendingMigration <long> >(); foreach (var nestedType in typeof(T).GetNestedTypes()) { var versionAttribute = nestedType.GetCustomAttribute <MigrationVersionAttribute>(); if (nestedType.IsClass && versionAttribute is not null) { var migration = new PendingMigration <long>(versionAttribute.Version, nestedType); testMigrations.Add(migration); } } var migrationPlan = approach == MigrationApproach.MigrationsWithNewerVersions ? await migrationEngine.GetPlanForNewMigrationsAsync() : await migrationEngine.GetPlanForNonAppliedMigrationsAsync(); var pendingMigrations = migrationPlan.PendingMigrations ! .Intersect(testMigrations) .ToList(); return(await migrationEngine.ApplyMigrationsAsync(pendingMigrations)); }