EntityFrameworkCore.Generator icon indicating copy to clipboard operation
EntityFrameworkCore.Generator copied to clipboard

Foreign-Key Relationship to Non-Primary Key doesn't generate .HasPrincipalKey(...) call in Map

Open DavidBoone opened this issue 9 months ago • 0 comments

If a table has a foreign-key relationship to another table's non-primary key, the required .HasPrincipalKey(...) call is not added to the Map file.

e.g.

CREATE TABLE thing (id int PRIMARY KEY, name text NOT NULL, parent_thing int REFERENCES thing(id));
CREATE TABLE other (id int PRIMARY KEY, thing_name text REFERENCES thing(name));

efg generate will create an OtherMap.cs containing:

        // relationships
        builder.HasOne(t => t.Thing)
            .WithMany(t => t.Others)
            .HasForeignKey(d => d.ThingName)
            .HasConstraintName("FK_Other_Thing_Name");

This results in a runtime error: The relationship from 'Other.Thing' to 'Thing.Others' with foreign key properties {'ThingName' : string} cannot target the primary key {'Id' : long} because it is not compatible. Configure a principal key or a set of foreign key properties with compatible types for this relationship.

The fix is to add the HasPrincipalKey call, e.g.:

        // relationships
        builder.HasOne(t => t.Thing)
            .WithMany(t => t.Others)
            .HasPrincipalKey(t => t.Name)
            .HasForeignKey(d => d.ThingName)
            .HasConstraintName("FK_Other_Thing_Name");

Unfortunately the next time efg generate is run that HasPrincipalKey line is wiped out.

I've attached a sample app/db illustrating the issue. It includes the manually added .HasPrincipalKey call so running the program is successful. Running efg generate will remove the line and cause the run-time failure.

ConsoleApp5.zip

DavidBoone avatar May 23 '24 19:05 DavidBoone