Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools: Default DOTNET_ENVIRONMENT to Development too #19903

Closed
Benalink opened this issue Feb 13, 2020 · 3 comments · Fixed by #21809
Closed

Tools: Default DOTNET_ENVIRONMENT to Development too #19903

Benalink opened this issue Feb 13, 2020 · 3 comments · Fixed by #21809
Assignees
Labels
area-scaffolding closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported poachable type-enhancement
Milestone

Comments

@Benalink
Copy link

When running Scaffold-DbContext, Named connection strings are not loaded from user secrets if a generic host project does not call .ConfigureWebHostDefaults().

I believe this is happening because only the ASPNETCORE_ENVIRONMENT variable is set and not the DOTNET_ENVIRONMENT variable in AppServiceProviderFactory.cs.

I feel like the expected behaviour is for named connection strings to be usable via User Secrets for both Asp and Worker Service projects. The other non environment conditional configuration sources can currently be used for Worker Services.

Steps to reproduce

  1. In Visual Studio, Create a Worker Service with the Worker Service template.
    Example of template

  2. Install ef core, a database provider and the ef core tools and also User Secrets.

    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.1" />
  1. Add your connection string to user secrets and scaffold using the named connection string.
dotnet user-secrets set ConnectionStrings.Chinook "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook"
dotnet ef dbcontext scaffold Name=Chinook Microsoft.EntityFrameworkCore.SqlServer
  1. Observe
System.InvalidOperationException: A named connection string was used, but the name 'Chinook' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application. See https://go.microsoft.com/fwlink/?linkid=850912 for more information.
   at Microsoft.EntityFrameworkCore.Storage.Internal.NamedConnectionStringResolverBase.ResolveConnectionString(String connectionString)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions)
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
A named connection string was used, but the name 'Chinook' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application. See https://go.microsoft.com/fwlink/?linkid=850912 for more information.
  1. Move connection string to appsettings.json (eek) and run the scaffold again.

Further technical details

EF Core version: 3.1.1
Database provider: Not provider specific but I used Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.4.4

@Benalink
Copy link
Author

The dotnet environment variable alone is not enough to get this working in a worker service as the assembly name will be ef when CreateDefaultBuilder is called by dbcontext scaffold.

If anyone else comes across this looking for a workaround. I've got around this issue by adding User Secrets whenever the application name is ef.

Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((ctx, config) =>
    {
        IHostEnvironment env = ctx.HostingEnvironment;
        // Check to see if we have been called by entity framework and need to load user-secrets for this assembly
        if (env.ApplicationName == "ef")
        {
            config.AddUserSecrets(Assembly.GetAssembly(typeof(Program)), optional: true);
        }
    })
    ...

@ajcvickers
Copy link
Member

Note for team: confirmed that generic host looks for "DOTNET_" while the web host looks for "ASPNETCORE_". She should probably support both, even though its more ugliness.

@ajcvickers
Copy link
Member

Team notes: we will handle both forms.

@ajcvickers ajcvickers self-assigned this Feb 21, 2020
@bricelam bricelam changed the title Scaffold-DbContext with named connection strings behaves differently when ran on a Worker Service project to an Asp Web project Tools: Default DOTNET_ENVIRONMENT to Development too Jun 5, 2020
bricelam added a commit to bricelam/efcore that referenced this issue Jul 27, 2020
@bricelam bricelam added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jul 27, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-rc1 Aug 14, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-rc1, 5.0.0 Nov 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-scaffolding closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported poachable type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants