简体   繁体   中英

Disabling the Implicitly created junction table for many-to-many relationship in Entity Framework

So, I am trying to create a Many-to-many relationship between Student & Supervisor object but I want to explicitly defining my StudentSupervisor class since I need to have additional properties in this junction class.

The problem is, when I checked in the migration file, EF automatically/implicitly created the junction table for the many-to-many relation and I don't want that.

The table EF implicitly created had the same name as my self-defined junction class StudentSupervisor, except with 1 at the end. (StudentSupervisor1).

I don't want this StudentSupervisor1 to be automatically created. Deleting it won't do anything since in every add-migration, it will be created again.

Thanks in advance.

Edit:

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

    public string Name { get; set; }

    public int FacultyId { get; set; }

    public Faculty Faculty { get; set; }

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

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

    public string MatricNo { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Supervisor> Supervisors { get; set; }
}

public class SupervisorStudents
{
    [Key, Column(Order = 0)]
    public int SupervisorId { get; set; }

    public Supervisor Supervisor { get; set; }

    [Key, Column(Order = 1)]
    public int StudentId { get; set; }

    public Student Student { get; set; }

    public string TagMainOrCo { get; set; }
}

and In my DbContext I'm using Fluent API to override them.

 modelBuilder
            .Entity<Student>()
            .HasKey(s => s.Id);

        modelBuilder
            .Entity<Supervisor>()
            .HasKey(p => p.Id);

        modelBuilder
            .Entity<SupervisorStudents>()
            .HasKey(a =>
                new
                {
                    a.StudentId, a.SupervisorId
                }
            );

        base.OnModelCreating(modelBuilder);

but as you can see in the migration file I have my SupervisorStudents table created and there is another SupervisorStudents1 (which is implicitly created by EF)

CreateTable(
            "dbo.SupervisorStudents",
            c => new
                {
                    SupervisorId = c.Int(nullable: false),
                    StudentId = c.Int(nullable: false),
                    TagMainOrCo = c.String(),
                })
            .PrimaryKey(t => new { t.SupervisorId, t.StudentId })
            .ForeignKey("dbo.Students", t => t.StudentId, cascadeDelete: true)
            .ForeignKey("dbo.Supervisors", t => t.SupervisorId, cascadeDelete: true)
            .Index(t => t.SupervisorId)
            .Index(t => t.StudentId);

 CreateTable(
            "dbo.SupervisorStudents1",
            c => new
                {
                    Supervisor_Id = c.Int(nullable: false),
                    Student_Id = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.Supervisor_Id, t.Student_Id })
            .ForeignKey("dbo.Supervisors", t => t.Supervisor_Id, cascadeDelete: true)
            .ForeignKey("dbo.Students", t => t.Student_Id, cascadeDelete: true)
            .Index(t => t.Supervisor_Id)
            .Index(t => t.Student_Id);

You're getting that other table because of the following properties:

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

public virtual ICollection<Supervisor> Supervisors { get; set; }

You're telling EF that Student has a direct relationship to Supervisor and that Supervisor has a direct relationship to Student . In order to support that EF must generate a table that relates those two entities.

Student has a collection of SupervisorStudents and Supervisor has a collection of SupervisorStudents . You can also get rid of the fluent configuration and just use annotations. The following should get you the correct result. I haven't had a chance to try it yet myself. If I get time this morning I'll give it a shot and update if needed.

public class Supervisor
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public int FacultyId { get; set; }

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

public class Student
{
    [Key]
    public int Id { get; set; }

    public string MatricNo { get; set; }

    public string Name { get; set; }

    public virtual ICollection<SupervisorStudents> Supervisors { get; set; }
}

public class SupervisorStudents
{
    [Key, Column(Order = 0)]
    public int SupervisorId { get; set; }

    [ForeignKey(nameof(SupervisorId))]
    public Supervisor Supervisor { get; set; }

    [Key, Column(Order = 1)]
    public int StudentId { get; set; }

    [ForeignKey(nameof(StudentId))]
    public Student Student { get; set; }

    public string TagMainOrCo { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM