EF Core 5 has various events, but they relate to DbContext
. There are no events related to migrations (Migration
).
I want to run custom code after all migrations are applied - whether triggered by code (context.Database.Migrate()
) or the CLI (dotnet ef database update
).
The workaround is to add an "empty" migration, and place my code in its Up
method. But I would need to do that every time I add a migration.
Assuming there's no event or hook I can use (is there?), how can I run custom code after all migrations are applied?
CodePudding user response:
Here's a workaround.
[DbContext(typeof(MyContext))]
[Migration("99999999999999_Last1")]
public class Last1 : Migration {
protected override void Up(MigrationBuilder migrationBuilder) {
Task.Run(() => callPostMigrationCodeThatIsIdempotent()).GetAwaiter().GetResult();
migrationBuilder.DeleteData(HistoryRepository.DefaultTableName, nameof(HistoryRow.MigrationId), "string", "99999999999999_Last2", null);
}
}
[DbContext(typeof(MyContext))]
[Migration("99999999999999_Last2")]
public class Last2 : Migration {
protected override void Up(MigrationBuilder migrationBuilder) {
Task.Run(() => callPostMigrationCodeThatIsIdempotent()).GetAwaiter().GetResult();
migrationBuilder.DeleteData(HistoryRepository.DefaultTableName, nameof(HistoryRow.MigrationId), "string", "99999999999999_Last1", null);
}
}
There are two "last" migrations:
- their ids are chosen so they run last ("99999999999999")
- both call the custom code, which must be idempotent
- each deletes the other from the history table
- they use
Task.Run
for async over sync
During each run one or the other runs the custom code, and deletes the other from the history table. On the next run the opposite would occur.
The same double setup can be used for a pre-migration hook.
There's an open backlog item on the repo.