Efcore: Migrations on class library projects

Created on 23 Jun 2018  路  6Comments  路  Source: dotnet/efcore

Hello!
We're developing a plugin framework for .NET game servers, which utilizes EntityFrameworkCore for database abstractions. We want to add migrations for our plugins, which are just normal .NET Standard class libraries.

At the moment it is not possible to generate such migrations:
Command: Add-Migration Initial -Project ExamplePlugin
Output:

Startup project 'ExamplePlugin' 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 Package Manager Console Tools with this project, add an executable project targeting .NET Framework or .NET Core that references this project, and set it as the startup project; or, update this project to cross-target .NET Framework or .NET Core.

A workaround is to create a dummy .exe project, like this:
https://github.com/RocketMod/Rocket.EntityFrameworkCore/blob/master/ExamplePluginMigrator/Program.cs

However, it is very inconvenient to create such migrators for every plugin project. Also you can only generate these migrations inside the migrator exe project, not in the dll plugin project, which prevents migrating programmatically.

Are there any plans on supporting migrations for class libraries in the future?

closed-question customer-reported

All 6 comments

Notice that Add-Migration supports both a -StartupProject and -Project, that are used to define the 'bootstrap' executable and the projects where migrations will be created.
So, even if it is inconvenient to have a (shared?) exe project just to kick-off migrations, you can still generate them in a target project.

This would not be such an big issue if said plugins were in the same solution.

Instead, each plugin has its own solution with its own projects (see http://github.com/RocketModPlugins), which are not executables. We would have to add dummy migrator exes to each of these solutions and would also require external plugin developers to do this for their plugin projects.

Enforcing developers to add

   public class Program
    {
        static void Main()
        {
            //dummy
        }
    }

to their projects to support migrations does not seems right.

As per this answer in SO, multi-trageting the project can help to overcome the issue... I know it is not a perfect solution, but I suppose it is the best short-term solution for this limitation... :(

That said, I suppose the tool should take care of all this stuff, without the need for workarounds...

in ef 6 have serializable model, in ef core there more startup nature, like ror, django , must use net core cli
I'm saying that what U could do in ef6 U not could do easily in ef core.

Maybe this would help !
https://github.com/aspnet/EntityFrameworkCore/issues/11819
https://github.com/aspnet/EntityFrameworkCore/issues/11851

@Trojaner25 This is an issue with the way .NET Standard class libraries work--that is, a class library needs to be used against an actual .NET implementation before the code in it can be executed. We have considered and attempted workarounds (close to hacks) for this in EF tooling, but they tend to make the situation worse rather than better because other parts of the .NET ecosystem then start to fail due to the EF hacks.

So...as much as it is a pain, we are not doing anything crazy to try to make this work, but instead we are suggesting ways people can work within the limitations of .NET Standard. These suggestions are:

  • Target only an executable framework (e.g. netcoreapp2.1) if you don't really need to target .NET Standard. This makes life easiest, but of course isn't always reasonable.
  • Use a standalone application, as you mention. This is the most reliable approach that allows both an unpolluted .NET Standard class library, and tooling to work with code built against a real target.
  • Cross compile the class library against a framework--e.g. netcoreapp2.1. As stated above, this can work. However, we are stepping back from recommending this because VS tooling still needs a bit of catch-up to make it work seamlessly. That said, we believe it works with VS as long as:

    • The executable target is listed first, and .NET Standard last

    • You use the new project system--that is new-style csproj--rather than the old

Hopefully this answers some of your questions!

Thanks @ajcvickers, this indeed answered my question. I will likely cross compile against netcoreapp2.1 for generating migrations.

Was this page helpful?
0 / 5 - 0 ratings