I have a solution with EF6-based database (code first) that has evolved a lot since the start of the project.
The large number of migrations causes the dll to grow large and creation of a new database to become very slow.
Is it possible to add a new 'initial' migration that results in the same state as the latest migration, and keep both migration-paths in the assembly?
Eg:
-> MInitial -> M2 -> M3 -> .. Mn -> MCurrent
add: *
-> MInitial2
(and in the future:) * -> MNext
An installation that is currently at M3 (or M2 / Mn) should follow the first migration-path (install all migrations up to Mcurrent). A new installtion should use MInitial2 to get to the current state.
Of course, future migrations should be 'compatible' with both MCurrent and MInitial2.
Thanks, Erik
_Sorry for copying my original post from StackOverflow, but nobody commented on that post
https://stackoverflow.com/questions/51855918/entity-framework-6-is-it-possible-and-safe-to-create-multiple-migration-path_
@ErikvdBurgwal I'm not sure what you mean by "keep both migration-paths in the assembly". I've certainly seen situations where older migrations are manually squashed into a single new migration, but in that case it ends up looking more like MInitial -> MSquashed -> MCurrent -> MNext.
@ajcvickers Thanks for your response Arthur!
My main concert is that I do not want to break the application.
Ideally, a new installation with the version MNext would install using the path MInitial -> MSquashed -> MCurrent -> MNext (in your words) or similar in my example; MInitial2 -> MNext. However, an update of an installation that is currently at M2 would follow the migrations M3 -> Mn -> MCurrent -> MNext.
Finally, both existing and new installations end-up with the current version (MNext), however, a new installation does not need to go through all separate migrations M2 .. Mn
@ErikvdBurgwal I don't believe that is possible with the migrations architecture.
@ErikvdBurgwal @ajcvickers I have this approach in one of my projects.
All the V1 migrations (V1.0 Initial...V1.1...V1.2...V1.n and a final V2.0) get moved to a 'legacy' V1 project along with an inherited DAL and a migrations configuration which includes an override to ensure the same context key.
In the main app include a V2.0 Initial migration and edit it to have the same ID as the final V2.0 migration in the V1 project. The final output should be the same.
In the DBInitializer for the main DBContext, do a call to GetPendingMigrations and check for the V1.0 Initial migration by name.
If it exists, create an instance of the V1 DBContext and trigger it's migrations (ignoring any AutomaticMigrationsDisabledException thrown as we may now be on V2.1 or higher).
Then get the migration history table and delete all V1.x migrations for the current ContextKey leaving _only_ the V2.0 Initial migration in the history.
Since the migration for V2.0 exists the main DBContext now has its 'first' migration applied and the state is consistent.
Now, whether it was on any V1.x state or empty, you can simply let the V2 migrations proceed. It will apply V2.0 initial if required, then any V2.1, V2.2 etc. after it.
There were a few tricks I had to pull to get this to work cleanly, and it is all testing, testing, testing after that, but it definitely makes life easier than applying 20+ migrations for a 'new' empty system (in my case).
You can repeat this when you get to V3.0 and allow any V1.x->V2.0 then any V2.x->V3.0 as well as Initial->V3.0 and then V3.x->V3.latest to keep things clean.
@CZEMacLeod Sounds good.
@CZEMacLeod thanks for your extensive response.
Although your proposed solution is not as simple as I hoped (mainly concerned about the amount of testing needed to cover all field scenario's), at least it is a clear description of a possible solution!
I consider to follow your approach, but move the V1 legacy project to a stand-alone "Db Updater" executable that I need to run (once) during installation on existing systems (for now that is acceptable as there are <10 installations). The advantage is that My V2 project does not need any reference to the V1 project.
Anyway, thanks for your feedback!