Reputation: 339
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
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