dotnet ef migrations fail when using custom output paths and separate project/startup-projects

See original GitHub issue

dotnet ef migrations fail when using custom output paths and separate project/startup-projects

Hi folks,

I’m trying to get my projects setup in docker and I’m running into this error:

error MSB4057: The target "GetEFProjectMetadata" does not exist in the project.

I used Brice’s suggestion here https://github.com/dotnet/efcore/issues/23691#issuecomment-754301900 and it works but only when everything is in a single project.

Other issues that are similar but I’m either missing a step or this is broken. #23691 #12220

Example repo

I have a repo with 4 scenarios here: https://github.com/chris-garrett/EfTools. I removed docker for the time being since this is reproducible without it.

  1. d180df5 Everything in one project with no modifications to output paths: Works
  2. 7f0c9b3 Everything in one project with modifications to output paths ([obj|bin]/containers): Works
  3. 1fb088e Separate projects for contexts / migration tool with no modifications to output paths: Works
  4. 5c264bc Separate projects for contexts / migration tool with modifications to output paths ([obj|bin]/containers): Does not work

Steps

# nuke any bin/obj folders
$ ./tools-nuke.sh

# create the migration
$ ./tool-create-migration.sh InitialMigration

# run the migration and verify its working
$ ./tool-migrate.sh

Verbose output

$ ./tool-create-migration.sh InitialMigration
Using project './EfTools.Data.csproj'.
Using startup project '../EfTools.Migrations/EfTools.Migrations.csproj'.
Writing 'obj/container/EfTools.Data.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpm1K4cl.tmp /verbosity:quiet /nologo ./EfTools.Data.csproj
Writing 'obj/container/EfTools.Migrations.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpKnaJFl.tmp /verbosity:quiet /nologo ../EfTools.Migrations/EfTools.Migrations.csproj                                                                                                                     
/mnt/nvme0/projects/dotnet/eftools/EfTools.Migrations/EfTools.Migrations.csproj : error MSB4057: The target "GetEFProjectMetadata" does not exist in the project.                                                                                                                           
Microsoft.EntityFrameworkCore.Tools.CommandException: 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.                     
   at Microsoft.EntityFrameworkCore.Tools.Project.FromFile(String file, String buildExtensionsDir, String framework, String configuration, String runtime)                                                                                                                                  
   at Microsoft.EntityFrameworkCore.Tools.RootCommand.Execute(String[] _)                                                                     
   at Microsoft.EntityFrameworkCore.Tools.Commands.CommandBase.<>c__DisplayClass0_0.<Configure>b__0(String[] args)                            
   at Microsoft.DotNet.Cli.CommandLine.CommandLineApplication.Execute(String[] args)                                                          
   at Microsoft.EntityFrameworkCore.Tools.Program.Main(String[] args)                                                                         
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. 

Provider and version information

EF Core version: 5.0.1 Database provider: Microsoft.EntityFrameworkCore.Sqlite Target framework: .NET 5.0.101 Operating system: Ubuntu 20.04.1 LTS IDE: command line

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:8
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

8reactions
georg-jungcommented, Jul 13, 2022

Was this postponed because the effort required did not justify the implementation, or the implementation was too complicated, or because the priority was too low?

I ask because this affects almost all projects I do with EF Core. My typical use case is:

I split my code into several csprojs:

  • one for the mvc/blazor/desktop/… UI app, “X.Web”
  • one for the context and migrations, “X.Data”
  • one for the models of the context, “X.Model”.

I regularly choose this approach because I think it has some advantages (if you think this choice is sub-par, let me know):

  • If I have a separate project for tooling/a nightly cronjob/maintenance/… I can just depend on the same data access code
  • each project can depend only on the packages it is supposed to depend on, ensuring clean separation at compile time (no one can accidentally use view-specific types in models, etc.; the X.Model could even be netstandard with Nullable if needed)

I also redirect my bin/ and obj/ folders to be at the root of the repo, similar to what @AArnott does in Library.Template. I think this has these advantages:

  • There is a constant path that contains the build artifacts. This makes it easy to collect them in DevOps pipelines and simplifies pipeline configuration.
  • Sometimes I want to manually delete the obj/ content if something goes wrong. This is really easy if obj/ is in the root of the repo.
  • I find it clean not to clutter the repo directory with build artifacts, but to have them in an easy to find place.

Because of this issue, the dotnet ef tooling breaks. I considered several options:

  1. Just use the Visual Studio’s ef tooling. This works, but doesn’t really feel right. It makes the ef commands unavailable in DevOps. So I could not create a migrationbundle as part of my CI/CD. It also excludes all non-VS/non-Windows contributors, leaving them with hard to understand error messages.
  2. Don’t redirect bin/ and obj/. Lose the benefits mentioned above.
  3. Only redirect bin/, not obj/. Works, but feels wrong. Hard to understand later or for new contributors. Clutters the repo directory with build artifacts in a rather strange way.
  4. Wait until this issue is fixed.

Obviously I was hoping for option 4 😉.

If you think what I’m doing is somehow weird or wrong or could be done better, please let me know. I would have thought this was a typical scenario for projects beyond very simple ones, but maybe I’m wrong when I look at the votes for this issue.

If you think that would be an option, I could try to create a PR for this, but you can probably better tell whether that makes sense to try.

2reactions
AgentEndercommented, Apr 10, 2023

Hey @bricelam, I hate to just come in with a “bump”, as a maintainer on a large OSS project myself I get that is not ideal…

That said, is there a status update of some kind on this issue? Aside from my work on Nx itself, I am the lead maintainer for the .NET plugin for it, and we redirect outputs into a folder that isn’t within the project root as a standard. We do so to better fit Nx’s conventions, and while its optional I’d like to continue to do that…

Nx has remote caching, and distributed task execution. These features combined lets you build a parent project (say your webapi), and kick off child projects building (class libraries, etc) on any number of machines. As dependant builds finish, and parent builds start, the build intermediates and results are downloaded onto the machine that will be running the parent build.

For large projects this is much, much faster.

If the intermediates folder is within the project root, specifying the cache locations and task inputs for build targets is a bit more complex than I’d like.

Is there anything I may be able to contribute which could further push this? My main reason for coming in with the bump is that we have the “punted-for7.0” tag, and 7.0 has released.


For reference, this is what our users end up running into: https://github.com/nx-dotnet/nx-dotnet/discussions/673

Read more comments on GitHub >

github_iconTop Results From Across the Web

EF Core add-migration Build Failed
Open Package Manager Console · Change directory to Migrations folder: cd C:\YourSolution\YourProjectWithMigrations · Enter in PM: dotnet ef ...
Read more >
Using a Separate Migrations Project - EF Core
Using a separate migration project for managing database schemas with Entity Framework Core.
Read more >
Untitled
Dotnet ef add migration startup project Web22 thg 1, 2017 · Sample. ... 2021 · dotnet ef migrations fail when using custom output...
Read more >
Managing Migrations - EF Core
Customize migration code​​ While EF Core generally creates accurate migrations, you should always review the code and make sure it corresponds to ...
Read more >
Entity Framework Core Migrations
NET project: To use migrations in EF Core, you start by defining your database schema using code, such as POCO classes and DbContext...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found