多对多的映射表
从我在网上看到的例子和编程entity frameworkCodeFirst的书中,当你在两个类上都有一个集合时,EF会创build一个映射表,比如MembersRecipes
,每个类的主键都会链接到这个表。
然而,当我做下面,我反而在Recipes
表中的Members
表中称为Member_Id
和Recipe_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
上的AuthorId
& Author
,我也将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; } }
在Recipe
和Member
类我改变了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) );