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 6.0.1 scaffold ignores table with many to may relation #2239

Closed
kobruleht opened this issue Jan 24, 2022 · 5 comments
Closed

dotnet-ef 6.0.1 scaffold ignores table with many to may relation #2239

kobruleht opened this issue Jan 24, 2022 · 5 comments

Comments

@kobruleht
Copy link

To reproduce, create database with tables containing many-to-many relation:

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) 
);

Scaffold database using 6.0.1 version of dotnet-ef :

dotnet ef dbcontext scaffold "Host=localhost;Database=eeva;UserName=postgres" Npgsql.EntityFrameworkCore.PostgreSQL --no-onconfiguring --no-build --context EevaScaffoldContext --force

Observed:

Artomadu.cs file is not created.

public virtual DbSet<Artomadu> Artomadus { get; set; }
statement is missing in generated code.

Artomadu table is referenced from Toode table configuring code:

                entity.HasMany(d => d.Artomaliiks)
                    .WithMany(p => p.Toodes)
                    .UsingEntity<Dictionary<string, object>>(
                        "Artomadu",
                        l => l.HasOne<Artomlii>().WithMany().HasForeignKey("Artomaliik").HasConstraintName("artomadu_artomaliik_fkey"),
                        r => r.HasOne<Toode>().WithMany().HasForeignKey("Toode").HasConstraintName("artomadu_toode_fkey"),
                        j =>
                        {
                            j.HasKey("Toode", "Artomaliik").HasName("artomadu_pkey");
                            j.IndexerProperty<int>("Artomaliik").HasColumnName("artomaliik");
                        });

In 6.0.0 version of dotnet-ef those tables caused InvalidOperationException as described in #2118

@kobruleht kobruleht changed the title dotnet-ef 6.0.1 scaffold ignores partially table with many to may realation dotnet-ef 6.0.1 scaffold ignores table with many to may relation Jan 25, 2022
@roji
Copy link
Member

roji commented Jan 25, 2022

This is by-design: EF Core 6.0 detects simple many-to-many join tables in the database, and does not scaffold an entity for them. If you create a database from that scaffolded model, you'll see the Artomadu being created. If you need to include it explicitly in a query, you can also do that; see the EF docs for more information.

@kobruleht
Copy link
Author

I need update, insert and delete Artomadu table like other tables.
Since Artomadu poco is not created, it is impossible.
Replacing primary key with surrogate id using

ALTER table artomadu drop constraint artomadu_pkey;
alter table artomadu add id serial primary key;

causes Artomadu class to be generated like for other tables.

@roji
Copy link
Member

roji commented Jan 25, 2022

Yes - this is once again by design - see dotnet/efcore#22475. When EF Core detects a simple join pattern - with no extra columns, just associations between the two sides - it doesn't scaffold an explicit entity for it, since in most cases that's not needed. Once you change the table and it's no longer identified as "simple", the entity gets scaffolded.

You can always add the explicit entity type yourself after scaffolding if you wish. See dotnet/efcore#22475 (comment) for a discussion, dotnet/efcore#4038 also tracks allowing users to opt out of this behavior and always scaffold the join table.

@roji
Copy link
Member

roji commented Jan 25, 2022

Duplicate of dotnet/efcore#4038

@roji roji marked this as a duplicate of dotnet/efcore#4038 Jan 25, 2022
@roji roji closed this as completed Feb 3, 2022
@JanneHarju
Copy link

JanneHarju commented Aug 19, 2022

My database has been using always numeric(10, 0) for some historic reasons. Scaffolding set datatype to decimal as it should where our code before EF is using long in C# side. So I have been using IDesignTimeServices to change them to be long in entities. My problem is related to this issue because many to many relation table is not going though IDesignTimeServices so it generates j.IndexerProperty("Lock").HasColumnType("numeric(10, 0)").HasColumnName("lock"); Where I would like to set data type to long instead of decimal because related table ID fields are long. Is there any way to affect how this part of code is generated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants