1

I have some EF Code First tables (one if them is ApplicationUser), and I'm trying to generate a migration to add a many-to-many relationship.

public class ApplicationUser : IdentityUser
{
    // many properties, not relevant here

    // NEW RELATIONSHIP
    public virtual ICollection<Trip> Trips { get; set; } = new HashSet<Trip>();
}

public class Trip
{
    // again, many properties

    public string ClientId { get; set; }

    [ForeignKey(nameof(ClientId))]
    public virtual ApplicationUser Client { get; set; }

    public string PartnerId { get; set; }

    [ForeignKey(nameof(PartnerId))]
    public virtual ApplicationUser Partner { get; set; }

    // NEW RELATIONSHIP
    public virtual ICollection<ApplicationUser> OtherUsers { get; set; } = new HashSet<ApplicationUser>();

}

Notice there's already a relationship in place (Trip has two foreign keys towards ApplicationUser, but I'm adding a new one.

When I run Add-Migration Trips in the console, this is generated:

public partial class Trips : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.AspNetUsers", "Trip_TripId", c => c.Int());
        AddColumn("dbo.Trips", "ApplicationUser_Id", c => c.String(maxLength: 128));
        CreateIndex("dbo.AspNetUsers", "Trip_TripId");
        CreateIndex("dbo.Trips", "ApplicationUser_Id");
        AddForeignKey("dbo.AspNetUsers", "Trip_TripId", "dbo.Trips", "TripId");
        AddForeignKey("dbo.Trips", "ApplicationUser_Id", "dbo.AspNetUsers", "Id");
    }

    public override void Down()
    {
        DropForeignKey("dbo.Trips", "ApplicationUser_Id", "dbo.AspNetUsers");
        DropForeignKey("dbo.AspNetUsers", "Trip_TripId", "dbo.Trips");
        DropIndex("dbo.Trips", new[] { "ApplicationUser_Id" });
        DropIndex("dbo.AspNetUsers", new[] { "Trip_TripId" });
        DropColumn("dbo.Trips", "ApplicationUser_Id");
        DropColumn("dbo.AspNetUsers", "Trip_TripId");
    }
}

Why is it creating two one-to-many relationships instead of one many-to-many? I was expecting a third table to be generated.

I have done this before with no problem, but I don't know if the fact that I already have foreign keys is interfering with the generation.

I've seen another answer that solves this using the Fluent API, but I've never needed to use it before. Is it really the only way to solve it? What am I doing wrong?

Community
  • 1
  • 1
Arturo Torres Sánchez
  • 2,751
  • 4
  • 20
  • 33

1 Answers1

1

I think you need an InverseProperty on one of the new collections. Try changing your Trip class as follows

// NEW RELATIONSHIP
[InverseProperty("Trips")]
public virtual ICollection<ApplicationUser> OtherUsers { get; set; } = new HashSet<ApplicationUser>();

That tells it the relationship is between the OtherUsers collection and the Trips property/collection.

More information at Using both many-to-many and one-to-many to same entity

Update: I notice the comments at the other question are ambiguous as to whether it works. I've not personally tried it with many-to-many relationships but this it works for situations such as Entity Framework, code-first: combining master-detail with zero-to-one relationship

I've be interested to hear if it works in your case.

Community
  • 1
  • 1
Tone
  • 1,701
  • 1
  • 17
  • 18