Repository navigation
ReadOnlyCollection<string> with private backing field throws exception on NullabilityInfoContext when trying to add migration #34996
Copy link
Copy link
Milestone
Description
Adding a Migration throws 'System.InvalidOperationException'
After adding a new public property with a private backing field to the model, the create and drop apis (context.Database.EnsureDeleted()/context.Database.EnsureCreated()) produce the expected database and table. But trying to add a new migration throws the following:
dotnet ef migrations add SampleMigration
Build started...
Build succeeded.
System.InvalidOperationException: Cannot scaffold C# literals of type 'System.Reflection.NullabilityInfoContext'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time.
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(Object value)
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.<Fragment>g__AppendMethodCall|57_0(IMethodCallCodeFragment current, <>c__DisplayClass57_0&)
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.Fragment(IMethodCallCodeFragment fragment, Int32 indent)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotations(String builderName, IAnnotatable annotatable, IndentedStringBuilder stringBuilder, Dictionary`2 annotations, Boolean inChainedCall, Boolean leadingNewline, MethodInfo hasAnnotationMethodInfo)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String modelBuilderName, IModel model, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMetadata(String migrationNamespace, Type contextType, String migrationName, String migrationId, IModel targetModel)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>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)
Cannot scaffold C# literals of type 'System.Reflection.NullabilityInfoContext'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time.Sample code
Please find the minimum code project here:
https://github.com/Red-F/EfCoreMigrationIssue
This was code added to the model
public IReadOnlyCollection<string> Uids => _uids.ToList();
private List<string> _uids = [];
public void AddUids(IEnumerable<string> uids)
{
_uids.AddRange(uids);
}
public void RemoveUids(IEnumerable<string> uids)
{
foreach (var uid in uids)
{
_uids.Remove(uid);
}
}Stack traces
See above.
Verbose output
dotnet ef --verbose migrations add SampleMigration
Using project '/home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj'.
Using startup project '/home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj'.
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpw9FrlF.tmp /verbosity:quiet /nologo /home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmp0ai4Yq.tmp /verbosity:quiet /nologo /home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj
Build started...
dotnet build /home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj /verbosity:quiet /nologo /p:PublishAot=false
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:01.88
Build succeeded.
dotnet exec --depsfile /home/fred/projects/EfCoreMigrationIssue/bin/Debug/net8.0/EfCoreMigrationIssue.deps.json --additionalprobingpath /home/fred/.nuget/packages --runtimeconfig /home/fred/projects/EfCoreMigrationIssue/bin/Debug/net8.0/EfCoreMigrationIssue.runtimeconfig.json /home/fred/.dotnet/tools/.store/dotnet-ef/9.0.0-rc.1.24451.1/dotnet-ef/9.0.0-rc.1.24451.1/tools/net8.0/any/tools/netcoreapp2.0/any/ef.dll migrations add SampleMigration --assembly /home/fred/projects/EfCoreMigrationIssue/bin/Debug/net8.0/EfCoreMigrationIssue.dll --project /home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj --startup-assembly /home/fred/projects/EfCoreMigrationIssue/bin/Debug/net8.0/EfCoreMigrationIssue.dll --startup-project /home/fred/projects/EfCoreMigrationIssue/EfCoreMigrationIssue.csproj --project-dir /home/fred/projects/EfCoreMigrationIssue/ --root-namespace EfCoreMigrationIssue --language C# --framework net8.0 --nullable --working-dir /home/fred/projects/EfCoreMigrationIssue --verbose
Using assembly 'EfCoreMigrationIssue'.
Using startup assembly 'EfCoreMigrationIssue'.
Using application base '/home/fred/projects/EfCoreMigrationIssue/bin/Debug/net8.0'.
Using working directory '/home/fred/projects/EfCoreMigrationIssue'.
Using root namespace 'EfCoreMigrationIssue'.
Using project directory '/home/fred/projects/EfCoreMigrationIssue/'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding DbContext classes in the project...
Found DbContext 'DemoDbContext'.
Finding application service provider in assembly 'EfCoreMigrationIssue'...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
Using application service provider from Microsoft.Extensions.Hosting.
Using context 'DemoDbContext'.
Finding design-time services referenced by assembly 'EfCoreMigrationIssue'...
Finding design-time services referenced by assembly 'EfCoreMigrationIssue'...
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 'EfCoreMigrationIssue'...
No design-time services were found.
System.InvalidOperationException: Cannot scaffold C# literals of type 'System.Reflection.NullabilityInfoContext'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time.
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(Object value)
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.<Fragment>g__AppendMethodCall|57_0(IMethodCallCodeFragment current, <>c__DisplayClass57_0&)
at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.Fragment(IMethodCallCodeFragment fragment, Int32 indent)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotations(String builderName, IAnnotatable annotatable, IndentedStringBuilder stringBuilder, Dictionary`2 annotations, Boolean inChainedCall, Boolean leadingNewline, MethodInfo hasAnnotationMethodInfo)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String modelBuilderName, IModel model, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMetadata(String migrationNamespace, Type contextType, String migrationName, String migrationId, IModel targetModel)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>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)
Cannot scaffold C# literals of type 'System.Reflection.NullabilityInfoContext'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time.```
### Include provider and version information
EF Core version: 9.0.0-rc.2.24473.5
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Linux
IDE: Rider/CLIReactions are currently unavailable
Activity
ajcvickers commentedon Oct 30, 2024
I was able to repro this with the following code:
Note the use of
Propertyfor a primitive collection. I'm not sure if this should even be allowed; we should discuss. IfPrimitiveCollectionis used, then the error goes away:@Red-F Is there a reason for using
Propertyhere instead ofPrimitiveCollection? (I recognize it's not clear thatPrimitiveCollectionshould be used here.)Move NonNullableConventionState to CoreAnnotationNames
Move NonNullableConventionState to CoreAnnotationNames
Move NonNullableConventionState to CoreAnnotationNames
Red-F commentedon Oct 31, 2024
@ajcvickers Why do we do the things that we do? A long time ago I saw a video where you discussed/explained this 'defensive copy' pattern. I liked that. A lot, because I think we need to make it as difficult as possible for ourselves to unintentionally make mistakes. So I use IReadOnlyCollection properties with a backing field of List everywhere.
SInce I like my code to be predictable for future me or new readers, that means I use IReadOnlyCollection<string> as well. Just to have no surprises for readers/reviewers.
I guess the same applies to the model configuration. Just predictably repeated configuration for all the collections. And to be honest, I also was not aware of .PrimitiveCollection(x => x.property). Even after reading your comment it took some effort to find it!
I was able to get it working using a workaround like
but my extensive reading of the online documentation (age will teach a person that reading documentation is a GOOD thing) had me convinced that the original code should work. In addition, the create and drop apis do work as intended, it is just that I can't create a migration (bundle).
Move NonNullableConventionState to CoreAnnotationNames
Move NonNullableConventionState to CoreAnnotationNames
14 remaining items
Move NonNullableConventionState to CoreAnnotationNames (#35020)
bbascarevic commentedon Jan 6, 2025
Hi @roji, any rough estimate on when may Design 9.0.2 land? This issue is keeping us from upgrading to EF 9.
Move NonNullableConventionState to CoreAnnotationNames (#35359)
roji commentedon Jan 16, 2025
@bbascarevic mid-Feb.