Description
When using EF Core scaffolding for an existing Postgres DB, I have started getting the following NullRef error. I have checked multiple versions of EF so I suspect a schema change - but I can't find any compelling changes that might cause it. Either way, shouldn't be getting a null ref.
The DB schema is provided by the open source application Waltz (https://github.com/finos/waltz).
I've reproduced this with a smaller subset of two tables in a couple of places in the schema (but definitely not affecting all tables with relationships).
Included is an example of just two tables that is throwing a null ref.
I've tried making public.person.employee_id
not nullable, but that doesn't seem stop the error.
Would someone be able to take a look?
Command to scaffold
dotnet ef dbcontext scaffold "<connection-string>" Npgsql.EntityFrameworkCore.PostgreSQL -o DataModels -c WaltzDbCont
ext -p App1 -f --no-onconfiguring --no-build --table involvement --table person --verbose
Output
Using project '[Redacted]\App1\App1 .csproj'.
Using startup project '[Redacted]\App1\App1 .csproj'.
Writing '[Redacted]\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\[Redacted]\AppData\Local\Temp\tmpFEB2.tmp /verbosity:quiet /nologo [Redacted]\App1\App1.csproj
Writing '[Redacted]\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\[Redacted]\AppData\Local\Temp\tmp172.tmp /verbosity:quiet /nologo [Redacted]\App1\App1.csproj
dotnet exec --depsfile [Redacted]\App1\bin\Debug\net7.0\App1.deps.json --additionalprobingpath C:\Users\[Redacted]\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages" --additionalprobingpath "C:\Program Files\dotnet\sdk\N
uGetFallbackFolder" --runtimeconfig [Redacted]\App1\bin\Debug\net7.0\App1.runtimeconfig.json C:\Users\[Redacted]\.dotnet\tools\.store\dotnet-ef\7.0.4\dotnet-ef\7.0.4\tools\net6.0\any\tools\netcoreapp2.0\any\ef.dll dbcontext scaffold [... Redacted ...]
Using assembly 'App1'.
Using startup assembly 'App1'.
Using application base '[Redacted]\App1\bin\Debug\net7.0'.
Using working directory '[Redacted]\App1'.
Using root namespace 'App1'.
Using project directory '[Redacted]\App1\'.
Remaining arguments: .
Finding design-time services referenced by assembly 'App1'...
Finding design-time services referenced by assembly 'App1'...
No referenced design-time services were found.
Finding design-time services for provider 'Npgsql.EntityFrameworkCore.PostgreSQL'...
Using design-time services from provider 'Npgsql.EntityFrameworkCore.PostgreSQL'.
Finding IDesignTimeServices implementations in assembly 'App1'...
No design-time services were found.
Found column with table: public.person, column name: id, data type: bigint, nullable: False, identity: True, default value: (null), computed value: (null)
Found column with table: public.person, column name: employee_id, data type: character varying(128), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: display_name, data type: character varying(255), nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: email, data type: character varying(255), nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: user_principal_name, data type: character varying(255), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: department_name, data type: character varying(255), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: kind, data type: character varying(255), nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: manager_employee_id, data type: character varying(128), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: title, data type: character varying(255), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: office_phone, data type: character varying(128), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: mobile_phone, data type: character varying(128), nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: organisational_unit_id, data type: bigint, nullable: True, identity: False, default value: (null), computed value: (null)
Found column with table: public.person, column name: is_removed, data type: boolean, nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.involvement, column name: entity_kind, data type: character varying(128), nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.involvement, column name: entity_id, data type: bigint, nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.involvement, column name: employee_id, data type: character varying(128), nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.involvement, column name: provenance, data type: character varying(64), nullable: False, identity: False, default value: 'waltz'::character varying, computed value: (null)
Found column with table: public.involvement, column name: kind_id, data type: bigint, nullable: False, identity: False, default value: (null), computed value: (null)
Found column with table: public.involvement, column name: is_readonly, data type: boolean, nullable: False, identity: False, default value: true, computed value: (null)
Found unique constraint with name: unique_employee_id, table: public.person.
For foreign key inv_kind_to_inv_fk on table public.involvement, unable to model the end of the foreign key on principal table public.involvement_kind. This is usually because the principal table was not included in the selection set.
The column 'public.involvement.is_readonly' would normally be mapped to a non-nullable bool property, but it has a default constraint. Such a column is mapped to a nullable bool property to allow a difference between setting the property to false and invoking the default constraint. See https://go.microsoft.com
/fwlink/?linkid=851278 for details.
The principal end of the foreign key 'public.involvement(employee_id)' is supported by the unique index 'unique_employee_id' and contains the following nullable columns 'public.person.employee_id'. Entity Framework requires the properties representing those columns to be non-nullable.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpDbContextGenerator.TransformText()
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpModelGenerator.ProcessTemplate(ITextTransformation transformation)
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpModelGenerator.GenerateModel(IModel model, ModelCodeGenerationOptions options)
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, String modelNamespace, String contextNamespace, Boolean useDataAnnot
ations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, String modelNamespace, String contextNamespace, Boolean useD
ataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
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)
Object reference not set to an instance of an object.
This example is between person
and involvement
, have found the same between involvement
and involvement_kind
, but they are the only two examples I have been able to find from a fairly large schema - so might be something directly related to the involvement
table - but processing this alone does not generate the error.
Provider and version information
EF Core version: 7.0.4 (have also tried 6.0.8, 6.0.15, 7.0,2 and this doesn't seem to make a difference)
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: .NET 7.0
Operating system: Windows 10
IDE: Terminal
dotnet ef --version
Entity Framework Core .NET Command-line Tools
7.0.4