EF Core Many to Many Issue Dual Types

c# entity-framework-core many-to-many

Question

I am trying to set up a many-to-many with additional properties in EF Core 2.2. After reading, it looks like I need to make my join table a first class citizen. I have done that, but the schema it is generating is not quite right. It's adding an unwanted shadow property called "UserId1".

Here is the domain model:

User.cs

 public class User : IdentityUser<long> {

        public string FirstName { get; set; }

        public string LastName { get; set; }
        public IList<UserJobRecommendations> RecommendedJobs { get; protected set; 
}

Job.cs

public class Job : BaseEntity<Job> {
    public long Id { get; protected set; }        
    public string Name {get ; protected set;}
    public IList<UserJobRecommendations> RecommendedTo { get; protected set; }
}

UserJobRecommendations.cs

public class UserJobRecommendations {
    public Job Job { get; protected set; }

    public long JobId { get; protected set; }
    public User User { get; protected set; }

    public long UserId { get; protected set; }

    public long RecommendedById { get; protected set; }
    public User RecommendedBy { get; protected set; }
    }

Finally, here is my context:

public class MyContext : IdentityDbContext<User, IdentityRole<long>, long> {
        public DbSet<Job> Jobs { get; set; }    
        public DbSet<UserJobRecommendations> UserJobRecommendations { get; set; }


        protected override void OnModelCreating(ModelBuilder modelBuilder) {            

            modelBuilder.Entity<UserJobRecommendations>().HasKey(k => new { k.UserId, k.JobId });

            modelBuilder.Entity<UserJobRecommendations>().HasOne(x => x.User).WithMany(x=>x.RecommendedJobs);
            modelBuilder.Entity<UserJobRecommendations>().HasOne(x => x.RecommendedBy);

            modelBuilder.Entity<User>().HasMany(x => x.RecommendedJobs);
            modelBuilder.Entity<Job>().HasMany(x => x.RecommendedTo);



            modelBuilder.Seed();
            base.OnModelCreating(modelBuilder);
        }

Here is a sample of the schema that it is creating for this. I don't want a userId1 property. The table should have 3 properties. JobId, UserId, RecommendedById.

  migrationBuilder.CreateTable(
                name: "UserJobRecommendations",
                columns: table => new
                {
                    JobId = table.Column<long>(nullable: false),
                    UserId = table.Column<long>(nullable: false),
                    UserId1 = table.Column<long>(nullable: true),
                    RecommendedById = table.Column<long>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_UserJobRecommendations", x => new { x.UserId, x.JobId });
                    table.ForeignKey(
                        name: "FK_UserJobRecommendations_Jobs_JobId",
                        column: x => x.JobId,
                        principalTable: "Jobs",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_UserJobRecommendations_AspNetUsers_RecommendedById",
                        column: x => x.RecommendedById,
                        principalTable: "AspNetUsers",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_UserJobRecommendations_AspNetUsers_UserId1",
                        column: x => x.UserId1,
                        principalTable: "AspNetUsers",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                });
1
1
12/18/2018 10:31:41 PM

Accepted Answer

Problem is in your Many-to-Many entity configuration. Your Many-to-Many configuration between User and Job is not written properly.

Write your entity configuration as follows:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{   
    base.OnModelCreating(modelBuilder);

    // Many-to-Many configuration between User and Job 
    modelBuilder.Entity<UserJobRecommendations>().HasKey(ujr => new { ujr.UserId, ujr.JobId });
    modelBuilder.Entity<UserJobRecommendations>().HasOne(ujr => ujr.User).WithMany(u=>u.RecommendedJobs)
                                                 .HasForeignKey(ujr => ujr.UserId).OnDelete(DeleteBehavior.Restrict);
    modelBuilder.Entity<UserJobRecommendations>().HasOne(ujr => ujr.Job).WithMany(j=>j.RecommendedJobs)
                                                 .HasForeignKey(ujr => ujr.JobId).OnDelete(DeleteBehavior.Restrict);

    // RecommendedBy ForeignKey Configuraiton
    modelBuilder.Entity<UserJobRecommendations>().HasOne(ujr => ujr.RecommendedBy).WithMany().HasForeignKey(ujr => ujr.RecommendedById);

    modelBuilder.Seed();

}

Now on Migration everything should generate as expected!

1
12/19/2018 5:00:33 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow