HelloThere
HelloThere

Reputation: 1040

Entity Framework Core fluent api One-To-Many and One-To-One produces duplicate foreign key

I'm changing my ASP.NET MVC project to ASP.NET Core MVC with Entity Framework Core and Fluent API. When I try to configure a one-to-one and one-to-many relationship, it generates duplicate foreign key columns in the dependent table.

For example: I have this in my context's OnModelCreating method:

builder.Entity<Session>()
       .HasKey(s=>s.Id);
builder.Entity<Session>()
       .Property(s=>s.CourseId)
       .IsRequired();
builder.Entity<Session>()
       .HasOne<Course>()
       .WithMany(c => c.Sessions)
       .HasForeignKey(s=>s.CourseId)
       .IsRequired();

Session model is like this:

public class Session
{
    public int Id { get; set; }

    // foreign key 
    public int CourseId { get; set; }

    // navigation properties
    public virtual Course Course { get; set; }
}

Course model is like this:

public class Course
{
    public int Id { get; set; }

    // Navigation properties
    public ICollection<Session> Sessions { get; set; }
}

Instead of getting this back in the migration:

modelBuilder.Entity("Blackboard.Models.DomainModels.Session", b =>
    {
        b.Property<int>("Id")
            .ValueGeneratedOnAdd();

        b.Property<int>("CourseId");

        b.HasKey("Id");

        b.HasIndex("CourseId");

        b.ToTable("Sessions");
   });

I get this:

 modelBuilder.Entity("Blackboard.Models.DomainModels.Session", b =>
    {
        b.Property<int>("Id")
            .ValueGeneratedOnAdd();

        b.Property<int>("CourseId");

        b.Property<int?>("CourseId1");

        b.HasKey("Id");

        b.HasIndex("CourseId");

        b.HasIndex("CourseId1");

        b.ToTable("Sessions");
   });

So even though I put .IsRequired(); for the relationship, the relationship seems to be made optional and an optional CourseId1 is added to the table.

The application is developed on Mac OSX with Visual Studio for Mac.

I've been configuring this for so long, I only found something for Entity Framework instead of Entity Framework Core. They two don't configure the same way. Can someone help me please?

Thank you.

Upvotes: 3

Views: 3402

Answers (1)

HelloThere
HelloThere

Reputation: 1040

I found a fix. I changed the context to:

builder.Entity<Session>()
   .HasOne(s=>s.Course)
   .WithMany(c => c.Sessions)
   .HasForeignKey(s=>s.CourseId)
   .IsRequired();

I remember I saw somewhere saying that if there is only one navigation property, then .HasOne<Type>()(no parameters passed) can be used. Obviously, it's not working. So always use lambda parameter in .HasOne.

Upvotes: 4

Related Questions