C# 多对多映射表

C# 多对多映射表,c#,entity-framework,ef-code-first,many-to-many,C#,Entity Framework,Ef Code First,Many To Many,根据我在网上和编程实体框架CodeFirst书中看到的示例,当两个类都有一个集合时,EF将创建一个映射表,如MembersRecipes,每个类的主键将链接到此表 但是,当我执行以下操作时,我在Recipes表中得到一个名为Member\u Id的新字段,并在Members表中得到一个Recipe\u Id 这只创建了两个一对多关系,但不是多对多关系,所以我可以让成员3链接到配方(4,5,6),配方4链接到成员(1,2,3)等等 有没有办法创建这个映射表?如果是这样的话,你怎么给它起个别的名字,

根据我在网上和编程实体框架CodeFirst书中看到的示例,当两个类都有一个集合时,EF将创建一个映射表,如
MembersRecipes
,每个类的主键将链接到此表

但是,当我执行以下操作时,我在
Recipes
表中得到一个名为
Member\u Id
的新字段,并在
Members
表中得到一个
Recipe\u 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; }
    }
Recipe
Member
类中,我将集合更改为

public virtual IList<MembersRecipes> MembersRecipes { get; set; }
public虚拟IList成员密码{get;set;}

在您的DbContext上执行以下操作:

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

谢谢你的快速回复,看起来不错,我只有一个问题。我得到了这个错误:“引用关系将导致不允许的循环引用。[Constraint name=FK\u Cookbooks\u Members\u MemberId]“我假设它与配方实体上的作者相关,但我不确定。谢谢,这很好,我找到了类似的帖子,但没有领会使用with many()的想法。”没有lambda表达式来配置所需的关系:许多在关系的另一端没有导航属性。当我把它看作是同一个作者链接到多个食谱时,这就更有意义了。谢谢希望我能再次+1。这也让我觉得我应该稍微重新构造一些东西,在“Cookbooks”关系映射表中使用可选的Owner标志,并删除Author属性,但我不确定是否可以将属性添加到Map()函数的产品中。您的多对多表Cookbooks将不再是无负载的,那么您需要不同的映射。对于确定多对多关系是否需要有效负载的指导原则,您可以从以下答案开始:感谢链接到该问题,我仍然不完全确定这意味着什么,但查看最佳实践说明,需要使用额外的ID字段,我猜想是因为Recipe&Member会以不同的方式引用多对多。我还没有完全试用我上面的更新,我注意到的一件事是我需要一种方法来确保每个配方在MembersRecipes表中至少有一个强制所有者标志。我想我可能会坚持我现在得到的,即使作者属性觉得多余。关于你的更新,在实体框架的说法中,多对多方法被称为多对多映射和有效载荷,我不知道为什么他们会提出一个非常奇特的术语(有效载荷);或者只是我,我的母语不是英语:-)我通常把payload这个词和计算机病毒联系起来。在EF中,有效负载并不是什么邪恶的东西,您可以通过使表成为有效负载就绪的实体(例如,通过添加额外的ID作为主键,因此您需要将现有的多对多组合pk转换为唯一的组合列)来证明您的设计。在您的情况下,您没有添加额外的ID,您维护了复合主键。表上的所有者标志是payload@MichaelBuen有效负载指的是映射表(关系),您可以在其中放入额外数据(例如关系的创建日期)。如果您应该在隐藏表中使用EF多对多,那么当我遇到此问题时,您无法为关系添加有效负载,因为我的导航属性之一是
列表
,另一个是
IEnumerable
。我将它们都更改为be列表,然后
Add Migration
开始生成一个XR表,而不仅仅是FK属性。
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");
});
modelBuilder.Entity<Recipe>()
    .HasRequired(x => x.Author)
    .WithMany()
    .WillCascadeOnDelete(false);
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)
);