dotnet ef migrations script -i -o scripts.sql
I can't find a way to generate one migration script for a project with multiple DbContexts
It kinda becomes an issue when you are trying to do it with VSTS CI/CD if you want to see the migration script first before you deploy it.
However, what I don't understand is when I use
dotnet ef database update -c ApplicationDbContext
It actually generates every DbContext with every migration.
but dotnet ef migrations script -i -o scripts.sql -c ApplicationDbContext only generates scripts for tables related to ApplicationDbContext.
Sounds like dbContext.Database.Migrate() is getting called (possibly from a Startup or a constructor) on every context when you call dotnet ef database update.
You can probably do some fancy shell scripting to get a script for every context:
dotnet ef dbcontext list | foreach {
dotnet ef migrations script -c $_ >> scripts.sql
}
Well, I thought about that. However, if I do that kinda script, how to make sure the migration history is the same?
For example:
00000000000000_CreateIdentitySchema
20180302222420_custom_tbl_name
20180309232758_InitialIdentityServerPersistedGrantDbMigration
20180309232832_InitialIdentityServerConfigurationDbMigration
The first 2 are from ApplicationDbContext. The 3rd and 4th are 2 other different DbContext.
What if I have another migration history for ApplicationDbContext in the end? The sequence for a new database will be different.
It might not be a problem because they are all different DBContexts.
However, I feel like there should be a way to generate a script just like calling dotnet ef database update
(I do have dbContext.Database.Migrate() in startup for ApplicationDbContext and have
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddTestUsers(Config.GetUsers())
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
});
)
It might not be a problem because they are all different DBContexts.
Correct. Migrations for different contexts shouldn't overlap (see also #2725). Their IDs are also sufficiently unique to never clash.
It shouldn't be a problem, but if it is, you can configure each context to have its own history table:
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlServer(
connectionString,
x => x.MigrationsHistoryTable("__MyMigrationsHistory"));
Most helpful comment
Sounds like
dbContext.Database.Migrate()is getting called (possibly from aStartupor a constructor) on every context when you calldotnet ef database update.You can probably do some fancy shell scripting to get a script for every context: