Many-to-many mapping table

c# ef-code-first entity-framework many-to-many

Question

According to samples I've seen online and in a book called Programming Entity Framework CodeFirst, EF would generate a mapping table if you had a collection of both types.MembersRecipes and each class's main key would connect to this table.

But when I do the following action, I instead get a new field in theRecipes named tableMember_Id and aRecipe_Id in theMembers table.

This just establishes two one-to-many connections, not a multitude of them, allowing me to link Member 3 to Recipes (4,5,6) and Recipe 4 to Members (1,2,3), for example.

Is it possible to build this mapping table? if so, how can you change the name to something different, like "cookbooks"?

Thanks

    public abstract class Entity {
        [Required]
        public int Id { get; set; }
    }   

    public class Member : Entity {
        [Required]
        public string Name { get; set; }

        public virtual IList<Recipe> Recipes { get; set; }
    }

    public class Recipe : Entity {  
        [Required]
        public string Name { get; set; }

        [ForeignKey("Author")]
        public int AuthorId { get; set; }
        public virtual Member Author { get; set; }

            ....

        public virtual IList<Member> Members { get; set; }
    }

UPDATE: Below is a different strategy I've tested that substitutes the Fluent API without using it.AuthorId & Author on Recipe I've also changed the name of the following example fromCookbooks to MembersRecipes This also resolves my problem in a manner similar to the response, however as already indicated, it has further repercussions.

public class MembersRecipes {

    [Key, Column(Order = 0)]
    [ForeignKey("Recipe")]
    public int RecipeId { get; set; }
    public virtual Recipe Recipe { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("Member")]
    public int MemberId { get; set; }
    public virtual Member Member { get; set; }

    public bool Owner { get; set; }
}

and inRecipe & Member classes The collections were changed to

public virtual IList<MembersRecipes> MembersRecipes { get; set; }
1
61
3/31/2016 4:40:55 AM

Accepted Answer

Apply the following to your DbContext OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{    
    modelBuilder.Entity<Recipe>()
        .HasMany(x => x.Members)
        .WithMany(x => x.Recipes)
    .Map(x =>
    {
        x.ToTable("Cookbooks"); // third table is named Cookbooks
        x.MapLeftKey("RecipeId");
        x.MapRightKey("MemberId");
    });
}

It's the same, simply another side of the same coin, and you can do it either way:

modelBuilder.Entity<Member>()
    .HasMany(x => x.Recipes)
    .WithMany(x => x.Members)
.Map(x =>
{
  x.ToTable("Cookbooks"); // third table is named Cookbooks
  x.MapLeftKey("MemberId");
  x.MapRightKey("RecipeId");
});

Other instances

http://www.ienablemuch.com/2011/07/using-checkbox-list-on-aspnet-mvc-with_16.html

http://www.ienablemuch.com/2011/07/nhibernate-equivalent-of-entity.html


UPDATE

In addition to what was said above, you must also include this to avoid cyclical references on your Author property:

modelBuilder.Entity<Recipe>()
    .HasRequired(x => x.Author)
    .WithMany()
    .WillCascadeOnDelete(false);

Source of the thought: With many to many self-referencing relationships, EF Code First

The fundamental issue is that you must notify EF that the Author property (a Member instance) contains no Recipe collections (denoted byWithMany() ); in this approach, cyclical reference on Author property might be halted.

The tables produced by the aforementioned Code First mappings are as follows:

CREATE TABLE Members(
    Id int IDENTITY(1,1) NOT NULL primary key,
    Name nvarchar(128) NOT NULL
);


CREATE TABLE Recipes(
    Id int IDENTITY(1,1) NOT NULL primary key,
    Name nvarchar(128) NOT NULL,
    AuthorId int NOT NULL references Members(Id)
);


CREATE TABLE Cookbooks(
    RecipeId int NOT NULL,
    MemberId int NOT NULL,
    constraint pk_Cookbooks primary key(RecipeId,MemberId)
);
98
5/23/2017 12:25:58 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