npgsql / efcore.pg

Entity Framework Core provider for PostgreSQL
PostgreSQL License
1.58k stars 227 forks source link

Scaffolding cross referenced tables throws InvalidOperationException in .NET 6 #2118

Closed kobruleht closed 3 years ago

kobruleht commented 3 years ago

Table ARTOMADU contains composite primary key from two columns, (TOODE, ARTOMALIIK) Those columns are foreign keys to TOODE and ARTOMALIIK tables.

TOODE table contains foreign key to ARTOMALIIK table on column TOOTEPUU

In this case .NET 6 scaffold tries to create duplicate propery name and fails with exception

System.InvalidOperationException: The property or navigation 'Toodes' cannot be added to the entity type 'Artomlii (Dictionary<string, object>)' because a property or navigation with the same name already exists on entity type 'Artomlii (Dictionary<string, object>)'.
   at Microsoft.EntityFrameworkCore.Metadata.Internal.EntityType.AddNavigation(MemberIdentity navigationMember, ForeignKey foreignKey, Boolean pointsToPrincipal)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.ForeignKey.Navigation(Nullable`1 propertyIdentity, ConfigurationSource configurationSource, Boolean pointsToPrincipal)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.ForeignKey.SetPrincipalToDependent(String name, ConfigurationSource configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.ForeignKey.Microsoft.EntityFrameworkCore.Metadata.IMutableForeignKey.SetPrincipalToDependent(String name)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.AddNavigationProperties(IMutableForeignKey foreignKey)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitForeignKeys(ModelBuilder modelBuilder, IList`1 foreignKeys)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitDatabaseModel(ModelBuilder modelBuilder, DatabaseModel databaseModel)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.Create(DatabaseModel databaseModel, ModelReverseEngineerOptions 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 useDataAnnotations, 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 useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluarlize)
   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)
The property or navigation 'Toodes' cannot be added to the entity type 'Artomlii (Dictionary<string, object>)' because a property or navigation with the same name already exists on entity type 'Artomlii (Dictionary<string, object>)'.

Table structures:

CREATE TABLE toode (
    toode character(20) primary key,
    tootepuu integer ,
    CONSTRAINT toode_tootepuu_fkey FOREIGN KEY (tootepuu)
        REFERENCES artomlii (artomaliik) 
);

CREATE TABLE artomlii (
    artomaliik integer primary key,
    treeparent integer,
    CONSTRAINT artomlii_treeparent_fkey FOREIGN KEY (treeparent)
        REFERENCES artomlii (artomaliik) 
);

CREATE TABLE artomadu (
    toode character(20) NOT NULL,
    artomaliik integer NOT NULL,
    CONSTRAINT artomadu_pkey PRIMARY KEY (toode, artomaliik),
    CONSTRAINT artomadu_artomaliik_fkey FOREIGN KEY (artomaliik)
        REFERENCES artomlii (artomaliik) ,
    CONSTRAINT artomadu_toode_fkey FOREIGN KEY (toode)
        REFERENCES toode (toode) 
);
roji commented 3 years ago

Duplicate of https://github.com/dotnet/efcore/issues/26496

roji commented 3 years ago

This is an EF Core bug (unrelated to Npgsql/PostgreSQL) which has already been fixed for 6.0.1.

kobruleht commented 3 years ago

6.0.1 is not avaliable in NuGet. How to upgrade to it? Tried to upgrade to daily builds using dotnet7 from

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    </packageSources>
</configuration>

but this causes compile error about missing Options class. It looks like this is not compatible with .NET 6 code.