efcore: `Optimize-DbContext` Does Not Fully Qualify Types, Resulting in Compile Errors

File a bug

When using Optimize-DbContext, the generated types are not fully qualified and/or do not fully resolve the generated type, resulting in compile errors.

I have identified 3 scenarios:

  1. The model type extends a class which has the same name of the class it extends (e.g. IdentityUser )
  2. The model type uses the same name as a type found in the System namespace (e.g. Index)
  3. The model type has the same name as the namespace in which it is located (e.g. Definition.Definition)

Include your code

I have committed a SLN with the generated compile errors here for your review: https://github.com/Mike-E-angelo/Stash/blob/master/EfCore6.Model/EfCore6.Model.sln

Include stack traces

NA

Include verbose output

PM> Optimize-DbContext -OutputDir Optimized -Verbose
Using project 'EfCore6.Model'.
Using startup project 'EfCore6.Model'.
Build started...
Build succeeded.
C:\Program Files\dotnet\dotnet.exe exec --depsfile ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\bin\Debug\net6.0\EfCore6.Model.deps.json --additionalprobingpath C:\Users\micha\.nuget\packages --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\bin\Debug\net6.0\EfCore6.Model.runtimeconfig.json C:\Users\micha\.nuget\packages\microsoft.entityframeworkcore.tools\6.0.0-preview.7.21378.4\tools\netcoreapp2.0\any\ef.dll dbcontext optimize --output-dir Optimized --verbose --no-color --prefix-output --assembly ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\bin\Debug\net6.0\EfCore6.Model.dll --project ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\EfCore6.Model.csproj --startup-assembly ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\bin\Debug\net6.0\EfCore6.Model.dll --startup-project ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\EfCore6.Model.csproj --project-dir ...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\ --language C# --working-dir ...\Mike-E-angelo\Stash\EfCore6.Model --root-namespace EfCore6.Model --nullable
Using assembly 'EfCore6.Model'.
Using startup assembly 'EfCore6.Model'.
Using application base '...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\bin\Debug\net6.0'.
Using working directory '...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model'.
Using root namespace 'EfCore6.Model'.
Using project directory '...\Mike-E-angelo\Stash\EfCore6.Model\EfCore6.Model\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'StorageBuilder'.
Found DbContext 'ApplicationState'.
Finding application service provider in assembly 'EfCore6.Model'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Using DbContext factory 'StorageBuilder'.
Using context 'ApplicationState'.
Finding design-time services referenced by assembly 'EfCore6.Model'...
Finding design-time services referenced by assembly 'EfCore6.Model'...
No referenced design-time services were found.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding IDesignTimeServices implementations in assembly 'EfCore6.Model'...
No design-time services were found.
The index {'UserId'} was not created on entity type 'IdentityUserRole<int>' as the properties are already covered by the index {'UserId', 'RoleId'}.
The index {'UserId'} was not created on entity type 'IdentityUserToken<int>' as the properties are already covered by the index {'UserId', 'LoginProvider', 'Name'}.
The property 'Index.UserId' was created in shadow state because there are no eligible CLR members with a matching name.
The property 'User.DefinitionId' was created in shadow state because there are no eligible CLR members with a matching name.
Successfully generated a compiled model, to use it call 'options.UseModel(ApplicationStateModel.Instance)'. Run this command again when the model is modified.
'ApplicationState' disposed.

Include provider and version information

EF Core version: 6.0.0-preview.7.21378.4 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: net6.0 Operating system: Windows 10 IDE: Visual Studio 2022 Preview 3.0

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 28 (12 by maintainers)

Commits related to this issue

Most upvoted comments

This tracks adding a simple commandline switch - https://github.com/dotnet/efcore/issues/27203

BTW about https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-6-0-preview-5-compiled-models/#comment-10060

I couldn’t answer because comments are now closed. You can use this to get your model “size”:

var model = context.Model;

Console.WriteLine("Model has:");
Console.WriteLine($"  {model.GetEntityTypes().Count()} entity types");
Console.WriteLine($"  {model.GetEntityTypes().SelectMany(e => e.GetDeclaredProperties()).Count()} properties");
Console.WriteLine($"  {model.GetEntityTypes().SelectMany(e => e.GetDeclaredForeignKeys()).Count()} relationships");

But the benefit you get from a compiled model also depends on the shape of your model. In general if the startup time wasn’t bothering you that much previously you probably won’t notice a difference with a compiled model.