When I implement many-to-many relationship between two classes, and configure its composite primary key using fluent api, then instead of creating 2 columns in the database, EF Core creates three columns.
UserReport.cs
public class UserReports
{
public int ReporterId { get; set; }
public User Reporter { get; set; }
public int ReporteeId { get; set; }
public User Reportee { get; set; }
}
User.cs
public class User: IdentityUser<int>
{
public DateTime DateOfBirth { get; set; }
public string KnownAs { get; set; }
public DateTime Created { get; set; }
public DateTime LastActive { get; set; }
public ICollection<UserReports> Reporters { get; set; } = new Collection<UserReports>();
public ICollection<UserReports> Reportees { get; set; } = new Collection<UserReports>();
}
ApplicatiobDbContext.cs
modelBuilder.Entity<UserReports>()
.HasKey(ru => new { ru.ReporterId, ru.ReporteeId});
modelBuilder.Entity<UserReports>()
.HasOne(ru => ru.Reportee)
.WithMany(u => u.Reporters)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<UserReports>()
.HasOne(ru => ru.Reporter)
.WithMany(u => u.Reportees)
.OnDelete(DeleteBehavior.Restrict);
Migration
After the adding the migrations the EF core generating this type of migration, which is creating an extra columns
ReporterId1 = table.Column<int>(nullable: true)
migrationBuilder.CreateTable(
name: "ReportUsers",
columns: table => new
{
ReporterId = table.Column<int>(nullable: false),
ReporteeId = table.Column<int>(nullable: false),
ReporterId1 = table.Column<int>(nullable: true),
Message = table.Column<string>(nullable: false)
},
You are missing the mention of HasForeignKey
in your configuration that's why the confusion for mapping the foreign key has been arisen as it is many-to-many
with same the entity. Update your configuration as follows:
modelBuilder.Entity<UserReports>()
.HasKey(ru => new { ru.ReporterId, ru.ReporteeId});
modelBuilder.Entity<UserReports>()
.HasOne(ru => ru.Reportee)
.WithMany(u => u.Reporters)
.HasForeignKey(ru => ru.ReporteeId); // <-- Here it is
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<UserReports>()
.HasOne(ru => ru.Reporter)
.WithMany(u => u.Reportees)
.HasForeignKey(ru => ru.ReporterId); // <-- Here it is
.OnDelete(DeleteBehavior.Restrict);