EF .Core 3.1 composite primary / foreign key problems after update from .NET Core 2.1

Viewed 771

I have two tables:

CREATE TABLE [dbo].[FormGridElementColumns]
(
    [FormGridElementColumnId] [uniqueidentifier] NOT NULL,
    [FormGridElementSchemaId] [uniqueidentifier] NOT NULL,
    [Caption] [nvarchar](256) NOT NULL,
    [Ordering] [int] NOT NULL,
    [Precision] [int] NULL
)

ALTER TABLE [dbo].[FormGridElementColumns] 
    ADD CONSTRAINT [PK_FormGridElementColumns] 
        PRIMARY KEY CLUSTERED ([FormGridElementSchemaId] ASC,
                               [FormGridElementColumnId] ASC)

and

CREATE TABLE [dbo].[FormGridElementColumnDataAdapters]
(
    [FormGridElementColumnDataAdapterId] [uniqueidentifier] NOT NULL,
    [FormGridElementColumnId] [uniqueidentifier] NULL,
    [FormGridElementSchemaId] [uniqueidentifier] NULL,
    [DisplayColumn] [nvarchar](256) NOT NULL
)

ALTER TABLE [dbo].[FormGridElementColumnDataAdapters] 
    ADD CONSTRAINT[PK_FormGridElementColumnDataAdapters] 
        PRIMARY KEY CLUSTERED ([FormGridElementColumnDataAdapterId] ASC)
GO

ALTER TABLE [dbo].[FormGridElementColumnDataAdapters] WITH CHECK 
    ADD CONSTRAINT [FK_FormGridElementColumnDataAdapters_FormGridElementColumns] 
        FOREIGN KEY ([FormGridElementSchemaId], [FormGridElementColumnId])
        REFERENCES [dbo].[FormGridElementColumns]([FormGridElementSchemaId], [FormGridElementColumnId])
            ON DELETE CASCADE

And models:

public class FormGridElementColumn
{
    public Guid FormGridElementColumnId { get; set; }
    public Guid FormGridElementSchemaId { get; set; }
    
    public string Caption { get; set; }
    public int Ordering { get; set; }
    public int? Precision { get; set; }

    public FormGridElementColumnDataAdapter FormElementDataAdapter { get; set; }
}

public class FormGridElementColumnDataAdapter
{
    public Guid FormGridElementColumnDataAdapterId { get; set; }

    public Guid? FormGridElementSchemaId { get; set; }
    public Guid? FormGridElementColumnId { get; set; }
    public string DisplayColumn { get; set; }
}

Everything worked well before the update. But after moving to .NET Core 3.1, I get the following error:

System.InvalidOperationException: The child/dependent side could not be determined for the one-to-one relationship between 'FormGridElementColumnDataAdapter' and 'FormGridElementColumn.FormElementDataAdapter'. To identify the child/dependent side of the relationship, configure the foreign key property. If these navigations should not be part of the same relationship configure them without specifying the inverse.

Trying to fix this in OnModelCreating:

    modelBuilder.Entity<FormGridElementColumn>(b =>
        {
            b.HasKey(p=> new {p.FormGridElementSchemaId, p.FormGridElementColumnId});
            ...
            b.HasOne(c => c.FormElementDataAdapter).WithOne().HasForeignKey<FormGridElementColumnDataAdapter>(k=> new{ k.FormGridElementSchemaId, k.FormGridElementColumnId});
            ...
            b.ToTable("FormGridElementColumns");
        });

But now I get other errors:

Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.
Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.
Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.
Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.
Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.
Invalid column name 'FormGridElementColumnFormGridElementSchemaId'.
Invalid column name 'FormGridElementColumnId1'.

Same error if I'm trying to add navigation property column into child entity (FormGridElementColumnDataAdapter).

Any help will be appreciated!

UPD1: I this possible that EF Core 3.1 has some changes related to keys types mapping? I have primary key as pair of non nullable Guids but foreign key is pair of nullable ones..not sure that this is the case but just trying to find solution.

1 Answers

You need to use navigation properties in your classes when you have a foreign key :

public class FormGridElementColumnDataAdapter
{
    public Guid FormGridElementColumnDataAdapterId { get; set; }
    
    //Using the object instead of the key
    public FormGridElementColumn FormGridElementColumn { get; set; }

    public string DisplayColumn { get; set; }
}

And in your model builder :

modelBuilder.Entity<FormGridElementColumn>(b =>
{
    b.HasOne(c => c.FormElementDataAdapter).WithOne(x => x.FormGridElementColumn).HasForeignKey<FormGridElementColumnDataAdapter>(k => new{ k.FormGridElementSchemaId, k.FormGridElementColumnId});
});
Related