Search code examples
c#entity-framework-coremany-to-manyef-fluent-api

How to change foreign key name in EF Core Fluent API?


I'm trying to make many to many relationships between two classes with EF Core fluent API. How can I change the foreign key names of the table between that will be created for this relationship?

For example, if we create a many-to-many relationship between the following two classes:

public class Student
{
    public int StudentId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

// Fluent Api
public class UserMap : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(x => x.Id);
        builder.ToTable("Users");

        builder.HasMany<Course>(user => user.Courses)
               .WithMany(course => course.Users);
    }
}

A table is created like this:

enter image description here

What I want is to create the in-between table with the foreign key names I give during code-first.

I know I can write the in-between table as a class and change the names with a one-to-many relationship, but I want to do it with code-first.

Example taken from EF core documentation.


Solution

  • You might want to add a new class for the in-between table:

    public class StudentCourse
    {
        public int FKStudentId { get; set; }
        public int FKCourseId { get; set; }
    
        public virtual Student Student { get; set; }
        public virtual Course Course { get; set; }
    
    }
    

    and replace the navigation properties:

    public virtual ICollection<Course> Courses { get; set; }
    

    with

    public virtual ICollection<StudentCourse> Courses { get; set; }
    

    do the same in the Course class.

    Then in the fluent Api, you can you now use the new class.

    public class StudentConfiguration : IEntityTypeConfiguration<Student>
    {
        public void Configure(EntityTypeBuilder<Student> entity)
        {
            entity.HasKey(x => x.StudentId);
    
            entity.HasMany(student => student.Courses)
                .WithOne(course => course.Student)
                .HasForeignKey(x => x.FKStudentId);
    
        }
    }
    
    public class CourseConfiguration : IEntityTypeConfiguration<Course>
    {
        public void Configure(EntityTypeBuilder<Course> entity)
        {
            entity.HasKey(x => x.CourseId);
    
            entity.HasMany(course => course.Students)
                .WithOne(stud => stud.Course)
                .HasForeignKey(x => x.FKCourseId);
    
        }
    }
    

    EDIT: If you don't want to add in-between class, you may want to try this:

            entity.HasMany(student => student.Courses)
                .WithMany(course => course.Students)
                .UsingEntity(x => x.Property("StudentsStudentId").HasColumnName("FKStudentId"));
    
            entity.HasMany(course => course.Students)
                .WithMany(stud => stud.Courses)
                .UsingEntity(x => x.Property("CoursesCourseId").HasColumnName("FKCourseId"));
    

    Note: "StudentsStudentId" and "CoursesCourseId" are generated by naming convention. So you may want to add migration first without the .UsingEntity() and inspect the generated migration.