Can I use EF Core migrations when EF code is spread over multiple solutions?

831 Views Asked by At

I'm working on a program that is composed of multiple projects in two different solutions.

We're using dot net 6.0's EF Core as an ORM, but the database was not created using EF, nor the EF model was created from the database (Don't ask me why, it was before I've joined the team).

Anyways, As no one on the team has a lot of experience with EF (including myself), and our team leader wants to know if we can use EF migrations to keep track of database - here's my question to you:

How can we use migrations if our EF code (entities and IEntityTypeConfiguration implementations) are spread over multiple projects in two (or more) solutions?

2

There are 2 best solutions below

0
On BEST ANSWER

Turns out the solution was stupidly simple, only had to read a lot and wait for the penny to drop - Here's what I've done at the end (currently as a POC, but I see no reason why it shouldn't work in the larger-scale actual project):

I've added a new dll project I've called Migrations to the solution that doesn't contain the DbContext class, added to it references of the project where the DbContext exists and references to all the other projects that have entities, and then created in that project a class that inherits the original DbContext of the project, and called it MigrationsDbContext. From that point, All I've had to do was to load all the relevant assemblies from my solution in the constructor of the MigrationsDbContext, and simply run the migrations on that class as my DbContext.

The benefit is that I only need to change one static property in one class from internal to protected internal for it to work with the real code and that's it.
The downside is that I'll have to add a reference to every new project with new entities, but that's a really small price to pay for not having to re-write the entire mess.

3
On

I recently did something similar when migrating from EF to EF Core. The process went something like this:

When data is split between solutions it will probably be easiest to manage by making them as independent as possible, i.e different database contexts, migrations, set of entities etc. We kept the data in the same database, but used different schemas for separation.

I'm not sure how well this will work if there is conceptually one database model shared between two solutions, but if that is the case you might want consider if that is a good idea. A 'Solution' implies a certain level of independence. I would probably also recommend keeping all of the database model, i.e. entities, migrations and context, to a single project.

You can create the database model from an existing database with the Scaffold-DbContext command. This should give you a baseline to start migrations from. The applied migrations are stored in a special __EFMigrationsHistory table. To handle old databases we just added that table with the 'InitialCreate' migration by hand. There might be some better way to handle this, and I would be glad to hear it in that case.

Once you have a base line you can change your entities and create migrations with Add-Migration. While working you can redo the migration by deleting the migration-file, reverting the dbContextModelSnapshot-file, and redoing add-Migration. You need to be careful if you are working in branches since migrations should be sequential. When merging you might just want to revert all migrations in one branch and re-create them.

We also made a separate tool that can:

  • Create the database(s)
  • Apply any migrations
  • Add default data to the database(s)

It is very nice to be able to recreate a default-database from scratch. If you get into some merge issue you might end up with a database that you cannot apply any migrations to. In that case it will probably be easiest to drop the database and recreate it using the correct sequence of migrations. You might also want some test-databases representing official releases so you can test that migrations work correctly for these, and make sure they contain some representative data.