web-dev-qa-db-ja.com

多対多のマッピングテーブル

オンラインおよびプログラミングエンティティフレームワークのCodeFirstブックで見た例から、両方のクラスのコレクションがある場合、EFはMembersRecipesなどのマッピングテーブルを作成し、各クラスの主キーはこのテーブルにリンクします。

ただし、以下を実行すると、代わりにRecipesテーブルにMember_Idと呼ばれる新しいフィールドと、MembersテーブルにRecipe_Idが追加されます。

これにより、2対1の関係のみが作成され、多対多の関係は作成されないため、メンバー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; }
    }

PDATE: Fluent APIを使用せず、AuthorIdAuthorRecipeを所有者に置き換える別の方法を試してみましたフラグ、以下の例の名前も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; }
}

RecipeMemberクラスでは、コレクションを

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

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


[〜#〜] update [〜#〜]

Authorプロパティでの循環参照を防ぐには、上記とは別に、これを追加する必要があります。

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

ここにあるアイデア: 多対多の自己参照関係を持つEF Code First

中心的なことは、Authorプロパティ(Memberインスタンス)にRecipeコレクション(WithMany()で示される)がないことをEFに通知する必要があることです。そうすれば、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)
);
_
95
Michael Buen