根据我在网上和 Programming Entity Framework CodeFirst 一书中看到的示例,当您在两个类上都有一个集合时,EF 会创建一个映射表,例如 MembersRecipes
和每个类的主键将链接到此表。
但是,当我执行以下操作时,我反而在 Recipes
表中获得了一个名为 Member_Id
的新字段,并且在 中获得了一个
表。Recipe_Id
>成员
这只会创建两个一对多关系,但不会创建多对多关系,因此我可以将成员 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 并将 Recipe
上的 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
类中,我将集合更改为
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
更新
为了防止对您的 Author 属性进行循环引用,除上述内容外,您还需要添加以下内容:
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()
表示);这样,就可以停止对 Author 属性的循环引用。
这些是从上面的 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)
);
关于c# - 多对多映射表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11382783/