This post was most recently updated on April 29th, 2022.3 min read.
This article explains how to achieve that nice configuration where you can reuse your .NET EF Core (Entity Framework Core) entities in different projects – even being separate from the project holding your DbContexts! You might want to do this if you have a common data model between a number of very different projects – but you will still need to have a way to add new migrations, apply the current ones to a database or possibly remove deprecated migrations. You can do this both with dotnet cli or EF Core PowerShell commandlets, but both of them come with some… Oddities.
I’ve run into issues with both – and the instructions below should help you with either option!
So, this is entirely supported, and not even that complicated, but actually getting the command right by memory seems to be nigh impossible… So better document it somewhere :)
Okay, so here are the steps – more or less – what you can do to fix the errors. Well, a couple of different errors, anyway.
Time needed: 15 minutes.
How to run EF Core commands for a different project?
You have configured your project somewhat like this:
– Contoso.DbAccess (contains your dbcontext(s)
– Contoso.Entities (contains your entities)
– Contoso.App (web app or desktop or whatever)
In my case, I had a couple of console applications and 2 Azure IoT Edge modules using the same entities, but only one of them needed the database context, hence the configuration.
- Select the right working directory
No matter where you run the commands from, this seems to be the best option – don’t use –project, rather cd to the directory that your DbContext project is in. I don’t know why, but it seems to work more stable for me this way.
Otherwise, you might get this error:
Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
No project was found. Change the current working directory or use the --project option.
So figure out which folder the project that you define your DbContext class(es) is in, and change that to be your working directory.
- Configure your startup project
With dotnet cli, you’ll need to add an executable project as the startup project by adding “–startup-project” and either the absolute or relative URI to your executable project’s .csproj-file.
dotnet ef migrations add NewMigration --startup-project "../Contoso.App/MyWebAppProject.csproj"
Remember that “../”! It’ll traverse one step up and then refer to your other project, in this case, a web app project. Or just use an absolute path instead.
This project can be any project that has .AddDbContext() or var db = new DbContext() -call in it. I have had the most consistent results with web projects, but that’s probably just a coincidence 🧐
With EF Core PowerShell commandlets, you should select the startup project from Solution Explorer.
- Make sure your startup project has your database context configured
Ah, this is pretty darn important. The project to which you’re referring with your –startup-project needs to have the database context configured one way or another.
One way to do this (for an ASP.NET Core web application with PostgreSQL database) would be shown below:
x => x.MigrationsAssembly("MyDbContext")));
Make note of the “x.MigrationsAssembly()” ! That part should reference the name of the assembly that actually has your DbContext and the code-first Migrations defined.
After all is said and done, our grand total of 2 commands to achieve this might look like the below (for dotnet cli):
cd Contoso.DbAccess dotnet ef migrations add NewMigration --startup-project "../Contoso.App/MyWebAppProject.csproj"
… and I suppose that’s it for now. These were the steps – and the accompanying errors – I have run into, so far.
Got one I haven’t encountered? Let me know in the comments section below! ☺
- EF Core migrations documentation: https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/projects?tabs=dotnet-core-cli
- Using role claims to target WebSockets - May 24, 2022
- The simplest fixes to “500 (Internal Server Error)” from Azurite - May 17, 2022
- How to solve “Npgsql: 42883: function create_hypertable(…) does not exist”? - May 10, 2022