The Secret to Running EF Core 2.0 Migrations from a NET Core or NET Standard Class Library

I have had two people that watched my Pluralsight EF Core Getting Started course (which will soon be joined by an EF Core 2: Getting Started course) ask the same question, which mystified me at first.

The were running migrations commands which caused the project to compile, but the commands did not do anything. For example, add-migration didn’t add a migration file. get-dbcontext did not return any information. The most curious part was there was no error message! I was able to duplicate the problem.

With EF6 it was possible to use migrations from a class library with no exe project in sight. EF Core migrations can run from a .NET Framework or .NET Core project but not .NET Standard. It needs a runtime. A common workaround is that even if you haven’t gotten to the UI part of your app yet, to just add a .NET Core console app project to the solution, add the EF Core Design Nuget package to it and set it as the startup project. But it’s still possible to do this without adding in a dummy project.

We already knew about the multi-targetting fix which solved an error when you try to run migrations from a .NET Standard library. But even with that fix in place, we were getting the mysterious nothingness.

The answer to the question was buried in a GitHub issue and in comments for the Migrations document in the EF Core docs. This same solution solved a problem I was having when trying to use migrations in a UWP app (again, not .NET Core or .NET Framework) that used a separate class library to host its DbContext.

I’m writing this blog post to surface the solution until it is resolved.

The solution that we used with EF Core 1.0 in order to run migrations from a .NET Standard library was to multi-target for .Net Standard (so you can use the library in a few places) and .NET Core (so you can run migrations).

That means replacing

<PropertyGroup>       
  <TargetFramework>netstandard20</TargetFramework>
</PropertyGroup>

with

<PropertyGroup> 
  <TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>

Notice that the attribute name is now plural and there is a semi-colon between the two SDKs.

But there’s one more secret which is not in the documentation.

For .NET Standard 2.0 (and EF Core 2.0), you also need to add the following to csproj.

<PropertyGroup>
 <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles></PropertyGroup>

Now with the DbContext project set as the startup and ensuring that the package manager console (or command line) are pointing to the same project, your migration commands will work.

Thanks to Christopher Moffat who found the solution in the GitHub issues and shared it in the comments on the EF Core Package Manager Console Tools document.


Screenshot for Tony ..see my comment in reply to your comment below.

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

6 thoughts on “The Secret to Running EF Core 2.0 Migrations from a NET Core or NET Standard Class Library

  1. I had this problem in the last weeks.
    I found needed to change the DLL to an EXE console and add inject an instance of the context in the startup . (core 2)
    I tried you suggestings without luck. The first change caused a compile error (Project targets ‘netcoreapp2.0’. It cannot be referenced by a project that targets ‘.NETStandard,Version=v2.0’.) and just having the second didn’t correct the class lib DLL only. I too thought it was a connection issue (moving from .config to json), and spent a few days down that road, but then I created a context (and needed an exe entry point to created it by changing the project output type), it all worked.

    My stackoverflow question on this issue https://stackoverflow.com/questions/48034663/ef-migrations-core2-dont-generate-on-dll-but-do-on-exe

    BTW, love your pluralsight courses… my first core app was a ninja wonder!!

    1. Tony,
      I’m confused. 🙂
      Your DLL is .NET Standard 2.0, but some other project that is also .NET Standard 2.0 is referencing it, right? Which is why you couldn’t do the multi-target solution so the next step of the solution (adding GenerateRuntimeConfigurationFiles) is moot?

      Just out of curiosity, what’s in the .NET Standard project that’s referencing the DLL? just a nicely designed solution with separation of concerns?

      I’ve built a solution that I believe follows what you are doing:

      domain classes dll is a NET Standard project
      data dll cross targets NET Standard and NET Core. This has a ref to domain project.
      netstandardclasslibrary targets only NET Standard. Has a ref to data and domain projects.

      Data DLL is startup and I was able to run a migrations command.

      I’ve added a screenshot to the bottom of the post so you can compare.

      Also, thanks for comment about my courses! I’m so glad they are a help to you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.