许多一对多映射表 [英] Many-to-many mapping table

查看:175
本文介绍了许多一对多映射表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我所看到的在网上和一个编程实体框架codeFirst书,当你有两个类EF将创建一个映射表,如 MembersRecipes 并从每个类的主键将链接到该表中。

然而,当我做下面,我反而获得 Member_Id 名为食谱表和一个新的领域 Recipe_Id 成员表。

其中仅创建了两个一到多的关系,而不是多到很多,所以我可以有会员3挂食谱(4,5,6)和配方4链接到会员(1,2,3 )等。

有没有一种方法来创建这个映射表?如果是这样,你如何将其命名为别的东西,如食谱?

感谢

 公共抽象类实体{
        [需要]
        公众诠释标识{搞定;组; }
    }    公共类会员:实体{
        [需要]
        公共字符串名称{;组; }        公共虚拟的IList<&配方GT;食谱{搞定;组; }
    }    公共类方药:实体{
        [需要]
        公共字符串名称{;组; }        [ForeignKey的(作者)]
        公众诠释AUTHORID {搞定;组; }
        公共虚拟会员作者{搞定;组; }            ....        公共虚拟的IList<&成员GT;成员{搞定;组; }
    }

更新:
下面是另一种方法我都试过不使用流利的API,并替换 AUTHORID &安培; 作者食谱与所有者标志,我也改名为从食谱下面的例子 MembersRecipes ,这也解决类似的回答我的问题,但提到有进一步的影响。

 公共类MembersRecipes {    [键,列(订单= 0)]
    [ForeignKey的(配方)]
    公众诠释RecipeId {搞定;组; }
    公共虚拟配方配方{搞定;组; }    [键,列(订单= 1)]
    [ForeignKey的(会员)]
    公众诠释MEMBERID {搞定;组; }
    公共虚拟会员会员{搞定;组; }    公共BOOL所有者获得{;组; }
}

食谱&安培; 成员类,我改变了馆藏

  public虚拟的IList< MembersRecipes> MembersRecipes {搞定;组; }


解决方案

做到这一点对你的DbContext OnModelCreating:

 保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
    modelBuilder.Entity<&配方GT;()
        .HasMany(X => x.Members)
        .WithMany(X => x.Recipes)
    .MAP(X =>
    {
        x.ToTable(食谱); //第三个表名为食谱
        x.MapLeftKey(RecipeId);
        x.MapRightKey(MEMBERID);
    });
}

您可以做它的其他方式太身边,这是同一枚硬币的一样,只是另一面:

  modelBuilder.Entity<&成员GT;()
    .HasMany(X => x.Recipes)
    .WithMany(X => x.Members)
.MAP(X =>
{
  x.ToTable(食谱); //第三个表名为食谱
  x.MapLeftKey(MEMBERID);
  x.MapRightKey(RecipeId);
});


进一步的例子:

<一个href=\"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

<一个href=\"http://www.ienablemuch.com/2011/07/nhibernate-equivalent-of-entity.html\">http://www.ienablemuch.com/2011/07/nhibernate-equivalent-of-entity.html


更新

要在你的Author属性prevent循环引用,除了上面,你需要补充一点:

  modelBuilder.Entity&LT;&配方GT;()
    .HasRequired(X =&GT; x.Author)
    .WithMany()
    .WillCascadeOnDelete(假);

在这里采购的理念:<一href=\"http://stackoverflow.com/questions/5273569/ef-$c$c-first-with-many-to-many-self-referencing-relationship\">EF code先用多对多的自我引用关系

核心的事情是,你需要告知EF的Author属性(这是一个成员实例)没有处方集(由 WithMany表示为());这样一来,循环参考可以停在Author属性。

以上是从code以上第一映射创建表:

  CREATE TABLE成员(
    ID INT IDENTITY(1,1)NOT NULL主键,
    名称为nvarchar(128)NOT NULL
);
CREATE TABLE食谱(
    ID INT IDENTITY(1,1)NOT NULL主键,
    名称为nvarchar(128)NOT NULL,
    AUTHORID诠释NOT NULL引用成员(ID)
);
CREATE TABLE食谱(
    RecipeId诠释NOT NULL,
    MEMBERID诠释NOT NULL,
    约束pk_Cookbooks主键(RecipeId,MEMBERID)
);

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 MembersRecipes and the primary key from each class would link to this table.

However when I do the below, I instead get a new field in the Recipes table called Member_Id and a Recipe_Id in the Members table.

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.

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 & Author on Recipe with an owner flag, I have also renamed the below example from Cookbooks to MembersRecipes, this also fixes my issue similar to the answer but as mentioned has further implications.

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 & Member classes I changed the collections to

public virtual IList<MembersRecipes> MembersRecipes { get; set; }

解决方案

Do this on your 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/nhibernate-equivalent-of-entity.html


UPDATE

To prevent cyclical reference on your Author property, aside from above, you need to add this:

modelBuilder.Entity<Recipe>()
    .HasRequired(x => x.Author)
    .WithMany()
    .WillCascadeOnDelete(false);

Idea sourced here: EF Code First with many to many self referencing relationship

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.

These are the created tables from the Code First mappings above:

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

这篇关于许多一对多映射表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆