Julien Guillot
Julien Guillot

Reputation: 339

EF Core Foreign Key configuration problem

i'm working on migrating actual office project to Entity Framework Core and .NET Core. I am stuck when i want to do Add-Migration. It seems Navigation Property and Foreign Key are not configured properly. After many trys i was not able to resolve my problem.

Error message when Add-Migration :

The relationship from 'PlanLang.Plan' to 'Plan.Lang' with foreign key properties {'PlanId' : int} cannot target the primary key {'GolfClubId' : int, 'PlanId' : int} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship.

Here are my Entities :

GolfClub

public class GolfClub
{
    public int Id { get; set; }
    //.. other properties, not important
}

Plan

public class Plan
{
    public int GolfClubId { get; set; }
    public int PlanId { get; set; }
    //.. other properties, not important

    public GolfClub GolfClub { get; set; }
    public ICollection<PlanLang> Lang { get; set; }
}

PlanLang

public class PlanLang
{
    public int GolfClubId { get;set; }
    public int PlanId { get; set; }
    public string Lang { get; set; }
    //.. other properties, not important

    public GolfClub GolfClub { get; set; }
    public Plan Plan { get; set; }
}

Here are my configurations :

public class GolfClubConfiguration : IEntityTypeConfiguration<GolfClub>
{
    public void Configure(EntityTypeBuilder<GolfClub> builder)
    {
        builder.ToTable("gc_master");

        builder.HasKey(k => new { k.Id });
        builder.Property(p => p.Id).ValueGeneratedNever(); // to disable auto-increment

    }
}

public class PlanConfiguration : IEntityTypeConfiguration<Plan>
{
    public void Configure(EntityTypeBuilder<Plan> builder)
    {
        builder.ToTable("gc_plan_master");

        builder.HasKey(k => new { k.GolfClubId, k.PlanId });
        builder.Property(p => p.GolfClubId).ValueGeneratedNever(); // to disable auto-increment

        builder.HasMany(p => p.Lang).WithOne(p => p.Plan).HasForeignKey(FK => FK.PlanId);
        builder.HasOne(p => p.GolfClub).WithMany().HasForeignKey(FK => FK.GolfClubId);
    }
}

public class PlanLangConfiguration : IEntityTypeConfiguration<PlanLang>
{
    public void Configure(EntityTypeBuilder<PlanLang> builder)
    {
        builder.ToTable("gc_plan_master_lang");

        builder.HasKey(k => new { k.GolfClubId, k.PlanId, k.Lang });
        builder.Property(p => p.GolfClubId).ValueGeneratedNever(); // to disable auto-increment
        builder.Property(p => p.Lang).HasMaxLength(5);

        builder.HasOne(p => p.GolfClub).WithMany().HasForeignKey(FK => FK.GolfClubId);
    }
}

What I want is that Plan has 1 foreign key (GolfClubId) and PlanLang 2 foreign keys (PlanId and GolfClubId).

Which way can I proceed to do so ?

Thank you for your responses.

Upvotes: 2

Views: 4294

Answers (1)

TanvirArjel
TanvirArjel

Reputation: 32109

Problem is in the GolfClubId of the PlanLang. Your Plan have List of PlanLang and GolfClubId in which individual PlanLang have GolfClubId which does not make sense and that's why EF Core cannot configuring/determining the relationship.

Remove GolfClubId from PlanLang because PlanLang is already related to GlofClub through Plan becase Plan has GolfClubId.

Write your model classes as follows:

public class GolfClub
{
    public int Id { get; set; }
    //.. other properties, not important
}

public class Plan
{
    public int PlanId { get; set; }
    public int GolfClubId { get; set; }

    //.. other properties, not important

    public GolfClub GolfClub { get; set; }
    public ICollection<PlanLang> PanLangs { get; set; }
}

public class PlanLang
{
    public int PlanId { get; set; }
    public string Lang { get; set; }
    //.. other properties, not important

    public Plan Plan { get; set; }
}

And rewrite the Plan and PlanLang EntityConfigurations as follows:

public class PlanConfiguration : IEntityTypeConfiguration<Plan>
{
    public void Configure(EntityTypeBuilder<Plan> builder)
    {
        builder.ToTable("gc_plan_master");

        builder.HasKey(k => k.PlanId);

        builder.HasMany(p => p.PlanLangs).WithOne(p => p.Plan).HasForeignKey(FK => FK.PlanId);
        builder.HasOne(p => p.GolfClub).WithMany().HasForeignKey(FK => FK.GolfClubId);
    }
}

public class PlanLangConfiguration : IEntityTypeConfiguration<PlanLang>
{
    public void Configure(EntityTypeBuilder<PlanLang> builder)
    {
        builder.ToTable("gc_plan_master_lang");

        builder.HasKey(k => new { k.PlanId, k.Lang });

        builder.Property(p => p.Lang).HasMaxLength(5);
        builder.HasOne(p => p.Plan).WithMany().HasForeignKey(FK => FK.PlanId);
    }
}

Now everything should work fine!

Upvotes: 1

Related Questions