多对多的映射表

从我在网上看到的例子和编程entity frameworkCodeFirst的书中,当你在两个类上都有一个集合时,EF会创build一个映射表,比如MembersRecipes ,每个类的主键都会链接到这个表。

然而,当我做下面,我反而在Recipes表中的Members表中称为Member_IdRecipe_Id一个新的领域。

这只会创build两个一对多的关系,但不是一个多对多的,所以我可以有成员3链接到食谱(4,5,6)和链接到成员(1,2,3)等4食谱

有没有办法创build这个映射表? 如果是这样的话,你怎么把它叫做“食谱”呢?

谢谢

  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; } } 

更新:下面是另一种方法,我已经尝试过不使用Fluent API,并使用所有者标志replaceRecipe上的AuthorIdAuthor ,我也将Cookbooks的以下示例重命名为MembersRecipes ,这也修复了类似于回答,但提到有进一步的影响。

 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; } } 

RecipeMember类我改变了collections

 public virtual IList<MembersRecipes> MembersRecipes { get; set; } 

在您的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"); }); } 

你也可以用另一种方式来做,也是一样的,只是同一枚硬币的另一面:

 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"); }); 

其他例子:

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

为了防止你的作者属性上的循环引用,除了上面的内容,你需要添加这个:

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

想法源于此: EF代码第一与许多到自我引用的关系

核心是,你需要告知EF,Author属性(它是一个成员实例)没有Recipe集合(用WithMany()表示); 这样,作者财产就可以停止循环引用。

这些是从上面的Code First映射创build的表格:

 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) );