从我在网上和编程实体框架CodeFirst一书中看到的示例中,当您在两个类上都有一个集合时,EF将创建一个映射表,例如MembersRecipes
,并且每个类的主键将链接到这张桌子。
但是,当我执行以下操作时,我会在Recipes
表格中Member_Id
和Recipe_Id
表中的Members
获取一个新字段。
只创建两个一对多关系,但不是多对多关系,所以我可以将成员3链接到食谱(4,5,6)和配方4链接到成员(1,2,3) )等等。
有没有办法创建这个映射表?如果是这样,你如何命名其他东西,如“烹饪书”?
由于
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并替换AuthorId
&amp; Author
Recipe
带有所有者标记,我还将以下示例从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
&amp; Member
个类我将集合更改为
public virtual IList<MembersRecipes> MembersRecipes { get; set; }
答案 0 :(得分:95)
在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
<强>更新强>
要防止对作者属性进行周期性引用,除此之外,您需要添加以下内容:
modelBuilder.Entity<Recipe>()
.HasRequired(x => x.Author)
.WithMany()
.WillCascadeOnDelete(false);
来源:EF Code First with many to many self referencing relationship
核心问题是,您需要通知EF Author属性(它是一个Member实例)没有Recipe集合(用WithMany()
表示);这样,可以在作者属性上停止循环引用。
这些是上面Code First映射中创建的表:
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)
);