C# 多对多映射表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11382783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Many-to-many mapping table
提问by Pricey
From examples that I have seen online and in a Programming Entity Framework CodeFirst book, when you have a collection on both classes EF would create a mapping table such as MembersRecipesand the primary key from each class would link to this table.
根据我在网上和编程实体框架 CodeFirst 书中看到的示例,当您在两个类上都有一个集合时,EF 将创建一个映射表,例如MembersRecipes每个类的主键将链接到该表。
However when I do the below, I instead get a new field in the Recipestable called Member_Idand a Recipe_Idin the Memberstable.
然而,当我做下面的,我不是在得到一个新的领域Recipes称为表Member_Id和Recipe_Id在Members表中。
Which only creates two one-to-many relationships, but not a many-to-many so I could have Member 3 linked to Recipes (4,5,6) and Recipe 4 linked to Members (1,2,3) etc.
这只会创建两个一对多关系,而不是多对多关系,因此我可以将成员 3 链接到食谱 (4,5,6) 并将食谱 4 链接到成员 (1,2,3) 等。
Is there a way to create this mapping table? and if so how do you name it something else such as "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 another approach I have tried which doesn't use the Fluent API and replaces the AuthorId& Authoron Recipewith an owner flag, I have also renamed the below example from Cookbooksto MembersRecipes, this also fixes my issue similar to the answer but as mentioned has further implications.
更新:下面是我尝试过的另一种方法,它不使用 Fluent API 并用所有者标志替换AuthorId& Authoron Recipe,我还将下面的示例从Cookbooksto重命名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; }
}
and in Recipe& Memberclasses I changed the collections to
在Recipe&Member类中,我将集合更改为
public virtual IList<MembersRecipes> MembersRecipes { get; set; }
采纳答案by Michael Buen
Do this on your DbContext OnModelCreating:
在您的 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");
});
}
You can do it the other way around too, it's the same, just another side of the same coin:
你也可以反过来做,它是一样的,只是同一枚硬币的另一面:
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");
});
Further examples:
进一步的例子:
http://www.ienablemuch.com/2011/07/using-checkbox-list-on-aspnet-mvc-with_16.html
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
http://www.ienablemuch.com/2011/07/nhibernate-equivalent-of-entity.html
UPDATE
更新
To prevent cyclical reference on your Author property, aside from above, you need to add this:
为了防止对您的 Author 属性进行循环引用,除上述之外,您还需要添加以下内容:
modelBuilder.Entity<Recipe>()
.HasRequired(x => x.Author)
.WithMany()
.WillCascadeOnDelete(false);
Idea sourced here: EF Code First with many to many self referencing relationship
想法来源于此处:EF Code First 具有多对多自引用关系
The core thing is, you need to inform EF that the Author property(which is a Member instance) has no Recipe collections(denoted by WithMany()); that way, cyclical reference could be stopped on Author property.
核心是,您需要通知 EF Author 属性(它是一个 Member 实例)没有 Recipe 集合(由 表示WithMany());这样,可以在 Author 属性上停止循环引用。
These are the created tables from the Code First mappings above:
这些是从上面的 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)
);

