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

dotnet ef dbcontext optimize failing with HasTrigger modifer on ToTable #32364

Closed
kev160967 opened this issue Nov 20, 2023 · 12 comments
Closed

Comments

@kev160967
Copy link

I am upgrading an EF6 project that uses a compiled model to EF8. When running the dbcontext optimize command I got an error that "The given key 'EntityType: ContainerService' was not present in the dictionary", ContainerService being one of the entities in my model. I narrowed the cause down to the ContainerService entity having a HasTrigger modifier:

    modelBuilder.Entity<ContainerService>(e => {
        e.ToTable("ContainerService", "depot",tb => tb.HasTrigger("trContainerService"));
    });

I confirmed this by removing the HasTrigger, at which point the error moved to the next entity that had HasTrigger set.

This is the reported stack trace

System.Collections.Generic.KeyNotFoundException: The given key 'EntityType: ContainerService' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.GetOrCreate(ITable table, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(ITableMapping tableMapping, String tableMappingsVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.<Create>g__CreateMappings|5_0(ITypeBase typeBase, String declaringVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters, <>c__DisplayClass5_0&)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(IRelationalModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.SqlServer.Design.Internal.SqlServerCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateAnnotations[TAnnotatable](TAnnotatable annotatable, Action`2 process, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateModelBuilder(IModel model, String namespace, Type contextType, Dictionary`2 entityTypeIds, Boolean nullable)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.GenerateModel(IModel model, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CompiledModelScaffolder.ScaffoldModel(IModel model, String outputDir, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String contextTypeName)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContextImpl(String outputDir, String modelNamespace, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

This is the tool output - there's a lot of it, so I have removed messages about explicit relationships, etc

Using project 'C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj'.
Using startup project 'C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj'.
Writing 'C:\Work\Saturn\Desktop\Master\Saturn.Data\obj\Saturn.Data.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\kevino\AppData\Local\Temp\tmpfxbfrq.tmp /verbosity:quiet /nologo C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj
Writing 'C:\Work\Saturn\Desktop\Master\Saturn.Data\obj\Saturn.Data.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\kevino\AppData\Local\Temp\tmp5n2b0x.tmp /verbosity:quiet /nologo C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj
Build started...
dotnet build C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj /verbosity:quiet /nologo /p:PublishAot=false

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.37
Build succeeded.
dotnet exec --depsfile C:\Work\Saturn\Desktop\Master\Saturn.Data\bin\Debug\net8.0-windows\Saturn.Data.deps.json --additionalprobingpath C:\Users\kevino\.nuget\packages --additionalprobingpath "C:\Program Files\DevExpress 22.2\Components\Offline Packages" --additionalprobingpath "C:\Program Files\DevExpress 23.1\Components\Offline Packages" --additionalprobingpath "C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages" --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Work\Saturn\Desktop\Master\Saturn.Data\bin\Debug\net8.0-windows\Saturn.Data.runtimeconfig.json C:\Users\kevino\.dotnet\tools\.store\dotnet-ef\8.0.0\dotnet-ef\8.0.0\tools\net8.0\any\tools\netcoreapp2.0\any\ef.dll dbcontext optimize -o Model\Compiled -n Saturn.Data.Model.Compiled --context Saturn.Data.Model.SaturnEntities --assembly C:\Work\Saturn\Desktop\Master\Saturn.Data\bin\Debug\net8.0-windows\Saturn.Data.dll --project C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj --startup-assembly C:\Work\Saturn\Desktop\Master\Saturn.Data\bin\Debug\net8.0-windows\Saturn.Data.dll --startup-project C:\Work\Saturn\Desktop\Master\Saturn.Data\Saturn.Data.csproj --project-dir C:\Work\Saturn\Desktop\Master\Saturn.Data\ --root-namespace Saturn.Data --language C# --framework net8.0-windows --working-dir C:\Work\Saturn\Desktop\Master\Saturn.Data --verbose
Using assembly 'Saturn.Data'.
Using startup assembly 'Saturn.Data'.
Using application base 'C:\Work\Saturn\Desktop\Master\Saturn.Data\bin\Debug\net8.0-windows'.
Using working directory 'C:\Work\Saturn\Desktop\Master\Saturn.Data'.
Using root namespace 'Saturn.Data'.
Using project directory 'C:\Work\Saturn\Desktop\Master\Saturn.Data\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'SaturnEntitiesDesignTimeContextFactory'.
Found DbContext 'SaturnEntities'.
Finding application service provider in assembly 'Saturn.Data'...
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...
Found DbContext 'SaturnProcs'.
Using DbContext factory 'SaturnEntitiesDesignTimeContextFactory'.
Using context 'SaturnEntities'.
Finding design-time services referenced by assembly 'Saturn.Data'...
Finding design-time services referenced by assembly 'Saturn.Data'...
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 'Saturn.Data'...
No design-time services were found.
System.Collections.Generic.KeyNotFoundException: The given key 'EntityType: ContainerService' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.GetOrCreate(ITable table, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(ITableMapping tableMapping, String tableMappingsVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.<Create>g__CreateMappings|5_0(ITypeBase typeBase, String declaringVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters, <>c__DisplayClass5_0&)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(IRelationalModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.SqlServer.Design.Internal.SqlServerCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateAnnotations[TAnnotatable](TAnnotatable annotatable, Action`2 process, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateModelBuilder(IModel model, String namespace, Type contextType, Dictionary`2 entityTypeIds, Boolean nullable)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.GenerateModel(IModel model, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CompiledModelScaffolder.ScaffoldModel(IModel model, String outputDir, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String contextTypeName)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContextImpl(String outputDir, String modelNamespace, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The given key 'EntityType: ContainerService' was not present in the dictionary.

Include provider and version information

EF Core version: 8.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: NET 8.0
Operating system: Windows 11 Pro x64
IDE: Visual Studio 2022 17.8.0

@ajcvickers
Copy link
Member

/cc @AndriySvyryd

@AndriySvyryd
Copy link
Member

@kev160967 Could you create a small repro project? Just the snippet you posted above is not enough to trigger this error.

@kev160967
Copy link
Author

kev160967 commented Nov 20, 2023

Thanks @AndriySvyryd . I've just put together a simple model example, and it works flawlessly. Clearly it must be something else in my model, but I'm not sure where yet and will need to do a bit more investigating. I've just commented out all of the HasTrigger actions and the compiled model builds with no issues. I then added a single one back in and again I'm getting the dictionary error. I'll investigate further in the morning, but any suggestions would be welcome!

Looking at the code I'd guess that it's failing on line 418:

var entityTypeVariable = metadataVariables[trigger.EntityType];

Perhaps I can narrow it down a bit by tracking through the code around this, to see if anything in my model might be triggering something related

@AndriySvyryd
Copy link
Member

Do you use any plugins, like EFCore.NamingConventions?

@kev160967
Copy link
Author

No, totally vanilla. This model was originally an ObjectContext/edmx based one. When I migrated the projects to net6 I wrote a translator to convert the edmx to fluent/code first, so pretty much everything is explicit. I've a meeting this morning, but afterwards my plan is to download the tooling locally and dig into what's going on. It's likely something weird about my model, but I'll report back here what I find, in case its useful

@kev160967
Copy link
Author

I'm struggling a little. I've built the project using build.cmd and opened it in VS2022 by dropping EFCore.sln on to startvs.cmd. I set up a debug launch profile to run dbcontext optimize on my test project. Initially it complained it couldn't find EF.DLL

The application to execute does not exist: 'C:\User\kevino\source\repos\efcore\artifacts\bin\dotnet-ef\Debug\net8.0\tools\netcoreapp2.0\any\ef.dll'

I could see three instance of ef.dll under attifacts, so tried copying the one from artifacts\bin\ef\Debug\netcoreapp2.0 to the location it was looking. This appeared to work, in as much as the command now completed and gave me the expected error, but I feel I may have missed something to need to do this?

I tried instrumenting the code in RelationalCSharpRuntimeAnnotationCodeGenerator, and debugging, but nothing seemed to make any difference. As a test I tried renaming the class, rebuilding again (both from VS and from build.cmd) and running again, but the error stack trace indicates that my version of the code was not being run, as the class name remained unchanged. Can you suggest what I might be missing?

@ErikEJ
Copy link
Contributor

ErikEJ commented Nov 21, 2023

@kev160967 Provide code for a runnable console app that reproduces the issue..

@kev160967
Copy link
Author

@ErikEJ Currently the only code I have that I can reproduce this on is the initial model I got the error on. I've taken a test copy of it, removed dependencies and trimmed off pieces here and there, and am still getting the error, and don't have any thoughts on what to remove next, short of trimming out entities until the error goes away. There are a lot of relationships though, and a lot of entities, so this isn't particularly simple. I could supply the resulting project (it's a library rather than a console app) but wouldn't want to post it in an open thread - happy to send to someone directly though?

@kev160967
Copy link
Author

Okay, I've reproduced the issue with a small project. To be honest, it looks fairly innocuous? One base type with two types inheriting from it. Attached zip file contains the project
Saturn.Data.zip

To reproduce the issue I ran the following command within the project directory:

dotnet ef dbcontext optimize -o Model\Compiled -n Saturn.Data.Model.Compiled --context Saturn.Data.Model.SaturnEntities

and here's the output:

Build started...
Build succeeded.
System.Collections.Generic.KeyNotFoundException: The given key 'EntityType: Location' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.GetOrCreate(ITable table, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(ITableMapping tableMapping, String tableMappingsVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.<Create>g__CreateMappings|5_0(ITypeBase typeBase, String declaringVariable, Dictionary`2 metadataVariables, CSharpRuntimeAnnotationCodeGeneratorParameters parameters, <>c__DisplayClass5_0&)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Create(IRelationalModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Design.Internal.RelationalCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.SqlServer.Design.Internal.SqlServerCSharpRuntimeAnnotationCodeGenerator.Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateAnnotations[TAnnotatable](TAnnotatable annotatable, Action`2 process, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.CreateModelBuilder(IModel model, String namespace, Type contextType, Dictionary`2 entityTypeIds, Boolean nullable)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpRuntimeModelCodeGenerator.GenerateModel(IModel model, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CompiledModelScaffolder.ScaffoldModel(IModel model, String outputDir, CompiledModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String contextTypeName)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContextImpl(String outputDir, String modelNamespace, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The given key 'EntityType: Location' was not present in the dictionary.

@kev160967
Copy link
Author

kev160967 commented Nov 22, 2023

Looks like it could be the inverse of this? That dictates adding HasTrigger only to the base class. If I do that I still get the error, but if I turn it around and add it to the derived classes I no longer get the error. I'm currently going through my original model adding in triggers and testing the model. I'll report back when I'm done

Interestingly this doesn't seem to be an issue until you have more than one inheriting entity?

@kev160967
Copy link
Author

Also I've just see this which sounds like it should be an alternative way to resolve my issue

@ajcvickers
Copy link
Member

Duplicate of #31627

@ajcvickers ajcvickers marked this as a duplicate of #31627 Dec 5, 2023
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants