Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extension point to Migrate #34199

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public virtual void UpdateDatabase(

var migrator = services.GetRequiredService<IMigrator>();

migrator.Migrate(targetMigration);
migrator.Migrate(targetMigration: targetMigration);
}

_reporter.WriteInformation(DesignStrings.Done);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public virtual MigrationFiles RemoveMigration(
if (force)
{
Dependencies.Migrator.Migrate(
migrations.Count > 1
targetMigration: migrations.Count > 1
? migrations[^2].GetId()
: Migration.InitialDatabase);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public static void Migrate(
Action<DbContext, IMigratorData>? seed,
string? targetMigration = null,
AndriySvyryd marked this conversation as resolved.
Show resolved Hide resolved
TimeSpan? lockTimeout = null)
=> databaseFacade.GetRelationalService<IMigrator>().Migrate(targetMigration, seed, lockTimeout);
=> databaseFacade.GetRelationalService<IMigrator>().Migrate(seed, targetMigration, lockTimeout);

/// <summary>
/// Asynchronously applies any pending migrations for the context to the database. Will create the database
Expand Down Expand Up @@ -213,7 +213,7 @@ public static Task MigrateAsync(
string? targetMigration = null,
TimeSpan? lockTimeout = null,
CancellationToken cancellationToken = default)
=> databaseFacade.GetRelationalService<IMigrator>().MigrateAsync(targetMigration, seed, lockTimeout, cancellationToken);
=> databaseFacade.GetRelationalService<IMigrator>().MigrateAsync(seed, targetMigration, lockTimeout, cancellationToken);

/// <summary>
/// Executes the given SQL against the database and returns the number of rows affected.
Expand Down
16 changes: 8 additions & 8 deletions src/EFCore.Relational/Migrations/IMigrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public interface IMigrator
/// Migrates the database to either a specified target migration or up to the latest
/// migration that exists in the <see cref="IMigrationsAssembly" />.
/// </summary>
/// <param name="targetMigration">
/// The target migration to migrate the database to, or <see langword="null" /> to migrate to the latest.
/// </param>
/// <param name="seed">
/// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied.
/// </param>
/// <param name="targetMigration">
/// The target migration to migrate the database to, or <see langword="null" /> to migrate to the latest.
/// </param>
/// <param name="lockTimeout">
/// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the
/// lock is released when the migration operation completes.
Expand All @@ -41,18 +41,18 @@ public interface IMigrator
/// </remarks>
[RequiresUnreferencedCode("Migration generation currently isn't compatible with trimming")]
[RequiresDynamicCode("Migrations operations are not supported with NativeAOT")]
void Migrate(string? targetMigration = null, Action<DbContext, IMigratorData>? seed = null, TimeSpan? lockTimeout = null);
void Migrate(Action<DbContext, IMigratorData>? seed = null, string? targetMigration = null, TimeSpan? lockTimeout = null);

/// <summary>
/// Migrates the database to either a specified target migration or up to the latest
/// migration that exists in the <see cref="IMigrationsAssembly" />.
/// </summary>
/// <param name="targetMigration">
/// The target migration to migrate the database to, or <see langword="null" /> to migrate to the latest.
/// </param>
/// <param name="seed">
/// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied.
/// </param>
/// <param name="targetMigration">
/// The target migration to migrate the database to, or <see langword="null" /> to migrate to the latest.
/// </param>
/// <param name="lockTimeout">
/// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the
/// lock is released when the migration operation completes.
Expand All @@ -66,8 +66,8 @@ public interface IMigrator
[RequiresUnreferencedCode("Migration generation currently isn't compatible with trimming")]
[RequiresDynamicCode("Migrations operations are not supported with NativeAOT")]
Task MigrateAsync(
string? targetMigration = null,
Func<DbContext, IMigratorData, CancellationToken, Task>? seed = null,
AndriySvyryd marked this conversation as resolved.
Show resolved Hide resolved
string? targetMigration = null,
TimeSpan? lockTimeout = null,
CancellationToken cancellationToken = default);

Expand Down
10 changes: 5 additions & 5 deletions src/EFCore.Relational/Migrations/IMigratorPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Microsoft.EntityFrameworkCore.Migrations;
/// <summary>
/// <para>
/// A service on the EF internal service provider that allows providers or extensions to execute logic
/// after <see cref="IMigrator.Migrate(string?, Action{DbContext, IMigratorData}?, TimeSpan?)"/> is called.
/// after <see cref="IMigrator.Migrate(Action{DbContext, IMigratorData}?, string?, TimeSpan?)"/> is called.
/// </para>
/// <para>
/// This type is typically used by providers or extensions. It is generally not used in application code.
Expand All @@ -20,7 +20,7 @@ namespace Microsoft.EntityFrameworkCore.Migrations;
public interface IMigratorPlugin
AndriySvyryd marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Called by <see cref="IMigrator.Migrate(string?, Action{DbContext, IMigratorData}?, TimeSpan?)"/> before applying the migrations.
/// Called by <see cref="IMigrator.Migrate(Action{DbContext, IMigratorData}?, string?, TimeSpan?)"/> before applying the migrations.
/// </summary>
/// <param name="context">The <see cref="DbContext" /> that is being migrated.</param>
/// <param name="data">The <see cref="IMigratorData" /> that contains the result of the migrations application.</param>
Expand All @@ -30,7 +30,7 @@ public interface IMigratorPlugin
void Migrating(DbContext context, IMigratorData data);

/// <summary>
/// Called by <see cref="IMigrator.MigrateAsync(string?, Func{DbContext, IMigratorData, CancellationToken, Task}?, TimeSpan?, CancellationToken)"/> before applying the migrations.
/// Called by <see cref="IMigrator.MigrateAsync(Func{DbContext, IMigratorData, CancellationToken, Task}?, string?, TimeSpan?, CancellationToken)"/> before applying the migrations.
/// </summary>
/// <param name="context">The <see cref="DbContext" /> that is being migrated.</param>
/// <param name="data">The <see cref="IMigratorData" /> that contains the result of the migrations application.</param>
Expand All @@ -46,7 +46,7 @@ Task MigratingAsync(
CancellationToken cancellationToken = default);

/// <summary>
/// Called by <see cref="IMigrator.Migrate(string?, Action{DbContext, IMigratorData}?, TimeSpan?)"/> after applying the migrations, but before the seeding action.
/// Called by <see cref="IMigrator.Migrate(Action{DbContext, IMigratorData}?, string?, TimeSpan?)"/> after applying the migrations, but before the seeding action.
/// </summary>
/// <param name="context">The <see cref="DbContext" /> that is being migrated.</param>
/// <param name="data">The <see cref="IMigratorData" /> that contains the result of the migrations application.</param>
Expand All @@ -56,7 +56,7 @@ Task MigratingAsync(
void Migrated(DbContext context, IMigratorData data);
AndriySvyryd marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Called by <see cref="IMigrator.MigrateAsync(string?, Func{DbContext, IMigratorData, CancellationToken, Task}?, TimeSpan?, CancellationToken)"/> after applying the migrations, but before the seeding action.
/// Called by <see cref="IMigrator.MigrateAsync(Func{DbContext, IMigratorData, CancellationToken, Task}?, string?, TimeSpan?, CancellationToken)"/> after applying the migrations, but before the seeding action.
/// </summary>
/// <param name="context">The <see cref="DbContext" /> that is being migrated.</param>
/// <param name="data">The <see cref="IMigratorData" /> that contains the result of the migrations application.</param>
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore.Relational/Migrations/Internal/Migrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Migrator(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual void Migrate(string? targetMigration, Action<DbContext, IMigratorData>? seed, TimeSpan? lockTimeout)
public virtual void Migrate(Action<DbContext, IMigratorData>? seed, string? targetMigration, TimeSpan? lockTimeout)
{
if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore
&& HasPendingModelChanges())
Expand Down Expand Up @@ -147,8 +147,8 @@ public virtual void Migrate(string? targetMigration, Action<DbContext, IMigrator
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual async Task MigrateAsync(
string? targetMigration,
Func<DbContext, IMigratorData, CancellationToken, Task>? seed,
string? targetMigration,
TimeSpan? lockTimeout = null,
CancellationToken cancellationToken = default)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public virtual void Can_apply_one_migration()
GiveMeSomeTime(db);

var migrator = db.GetService<IMigrator>();
migrator.Migrate("Migration1");
migrator.Migrate(targetMigration: "Migration1");

var history = db.GetService<IHistoryRepository>();
Assert.Collection(
Expand All @@ -181,8 +181,8 @@ public virtual void Can_revert_all_migrations()
GiveMeSomeTime(db);

var migrator = db.GetService<IMigrator>();
migrator.Migrate("Migration5");
migrator.Migrate(Migration.InitialDatabase);
migrator.Migrate(targetMigration: "Migration5");
migrator.Migrate(targetMigration: Migration.InitialDatabase);

var history = db.GetService<IHistoryRepository>();
Assert.Empty(history.GetAppliedMigrations());
Expand All @@ -197,8 +197,8 @@ public virtual void Can_revert_one_migrations()
GiveMeSomeTime(db);

var migrator = db.GetService<IMigrator>();
migrator.Migrate("Migration5");
migrator.Migrate("Migration4");
migrator.Migrate(targetMigration: "Migration5");
migrator.Migrate(targetMigration: "Migration4");

var history = db.GetService<IHistoryRepository>();
Assert.Collection(
Expand All @@ -221,7 +221,7 @@ public virtual void Can_apply_one_migration_in_parallel()
{
using var context = Fixture.CreateContext();
var migrator = context.GetService<IMigrator>();
migrator.Migrate("Migration1");
migrator.Migrate(targetMigration: "Migration1");
});

var history = db.GetService<IHistoryRepository>();
Expand All @@ -242,7 +242,7 @@ await Parallel.ForAsync(0, Environment.ProcessorCount, async (i, _) =>
{
using var context = Fixture.CreateContext();
var migrator = context.GetService<IMigrator>();
await migrator.MigrateAsync("Migration1");
await migrator.MigrateAsync(targetMigration: "Migration1");
});

var history = db.GetService<IHistoryRepository>();
Expand All @@ -257,13 +257,13 @@ public virtual void Can_apply_second_migration_in_parallel()
using var db = Fixture.CreateContext();
db.Database.EnsureDeleted();
GiveMeSomeTime(db);
db.GetService<IMigrator>().Migrate("Migration1");
db.GetService<IMigrator>().Migrate(targetMigration: "Migration1");

Parallel.For(0, Environment.ProcessorCount, i =>
{
using var context = Fixture.CreateContext();
var migrator = context.GetService<IMigrator>();
migrator.Migrate("Migration2");
migrator.Migrate(targetMigration: "Migration2");
});

var history = db.GetService<IHistoryRepository>();
Expand All @@ -279,13 +279,13 @@ public virtual async Task Can_apply_second_migration_in_parallel_async()
using var db = Fixture.CreateContext();
await db.Database.EnsureDeletedAsync();
await GiveMeSomeTimeAsync(db);
await db.GetService<IMigrator>().MigrateAsync("Migration1");
await db.GetService<IMigrator>().MigrateAsync(targetMigration: "Migration1");

await Parallel.ForAsync(0, Environment.ProcessorCount, async (i, _) =>
{
using var context = Fixture.CreateContext();
var migrator = context.GetService<IMigrator>();
await migrator.MigrateAsync("Migration2");
await migrator.MigrateAsync(targetMigration: "Migration2");
});

var history = db.GetService<IHistoryRepository>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ public string GenerateScript(
MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
=> throw new NotImplementedException();

public void Migrate(string targetMigration, Action<DbContext, IMigratorData> seed, TimeSpan? lockTimeout)
public void Migrate(Action<DbContext, IMigratorData> seed, string targetMigration, TimeSpan? lockTimeout)
=> throw new NotImplementedException();

public Task MigrateAsync(string targetMigration,
Func<DbContext, IMigratorData, CancellationToken, Task> seed,
public Task MigrateAsync(Func<DbContext, IMigratorData, CancellationToken, Task> seed,
string targetMigration,
TimeSpan? lockTimeout,
CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
Expand Down