Date posted: 23 Apr 2020, 2 minutes to read

Using EntityFramework Core tooling with .NET Standard

I want to target .NET Standard so I can always use my libraries in any project later on, independently of its target framework (as long as it supports the .NET Standard version I’m targeting).

unsplash-logoPhoto by Hans Vivek

Today I had an issue with using the Entity Framework Core tools in a .NET Standard Library: the EF Core tools don’t support the .NET Standard framework: they can only target .NET Core or .NET Classic (Full framework).

This means that when you use a .NET Standard project to host your database setup in, you will get a nice error message when you run dotnet ef migrations add InitialCreate:

Startup project 'Provisioning.DataLibrary.csproj' targets framework '.NETStandard'. There is no runtime associated with this framework, and projects targeting it cannot be executed directly. To use the Entity Framework Core .NET Command-line Tools with this project, add an executable project targeting .NET Core or .NET Framework that references this project, and set it as the startup project using --startup-project; or, update this project to cross-target .NET Core or .NET Framework. For more information on using the EF Core Tools with .NET Standard projects, see https://go.microsoft.com/fwlink/?linkid=2034781

The documentation link does point you in the right direction, but it wasn’t as easy to find. Next time I run into this issue, I should be able to find the solution quicker 😄.

Do note: I happen to still have the version ‘2.2.0-rtm-35687’ of the EF Core tools installed, not sure how this behavior is with the newer versions.

Solution setup

The docs already indicate to create a dummy project with a dependency on the .NET Standard Library. What they don’t clearly explain, is that you then need to do some extra steps to get the EF Core tooling (like migrations) working.

Screenshot of the solution folders I’ve setup my solution like above:

  • Provisioning.DataLibrary holds the DbContext with all of its models and targets .NET Standard 2.0 in this case.
  • Provisioning.ConsoleApp is the dummy project with a dependency on the DataLibrary and targets .NET Core 3.1.

You need to add the EF Core designer package to the dummy project for it to get all the commands you want to use:

cd Provisioning.ConsoleApp
dotnet add package Microsoft.EntityFrameworkCore.Design

Also note that I am using the appsettings.json to read the connection string to the database to use for EntityFramework, so I’ve included them to the console app: that is what EF Core will be using for running everything, so it needs to find those files as well (don’t forget to mark them as Copy always to actually get them in the correct bin folder.).

I usually open the Package Manager Console to execute actions like calling the EF Core Tools, just to stay in the same window. If you open it, you will start in the folder of the solution file. To use the EF Core tools, you’d normally change into the correct folder: in this case Provisioning.DataLibary ad then run the tools, like the migration actions:

cd Provisioning.DataLibrary
dotnet ef migrations add InitialCreate

This will give you the error above: Provisioning.DataLibrary is a .NET Standard library and the tools cannot analyze this.

Correct commands

To get the EF Core tools to work, you can stay in the main (solution) folder and indicate everything the tools need to find the correct references:

dotnet ef migrations add InitialCreate --project Provisioning.DataLibrary --startup-project Provisioning.ConsoleApp

So, with --project Provisioning.DataLibrary it knows where it needs to create the migrations + folders for it. And with --project Provisioning.ConsoleApp it can find a .NET Core project to target.

In the end it’s not that complicated, but certainly not intuitive.