オンラインおよびプログラミングエンティティフレームワークの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を使用せず、AuthorId
のAuthor
とRecipe
を所有者に置き換える別の方法を試してみましたフラグ、以下の例の名前も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
[〜#〜] 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)
);
_