从我在网上和《编程实体框架》 CodeFirst书中看到的示例中,当您在两个类上都有一个集合时,EF会创建一个映射表,例如MembersRecipes,每个类的主键都将链接到该表。
MembersRecipes
但是,当我执行以下操作时,我改为在Recipes表中获得一个新字段,Member_Id并Recipe_Id在该Members表中获得a 。
Recipes
Member_Id
Recipe_Id
Members
这只会创建两个一对多的关系,而不是一对多的关系,因此我可以将Member 3链接到食谱(4,5,6),将Recipe 4链接到成员(1,2,3)等。
有没有创建此映射表的方法?如果是的话,您如何命名其他名称,例如“ cookbooks”?
谢谢
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; } }
更新: 以下是我尝试过的另一种方法,该方法不使用Fluent API,并用所有者标志替换AuthorId&Author上Recipe的内容,我还将以下示例从重命名Cookbooks为MembersRecipes,这也解决了与答案类似的问题,但如上所述进一步的含义。
AuthorId
Author
Recipe
Cookbooks
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班级中,我将集合更改为
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
更新
为了防止对Author属性进行周期性引用,除了上面的内容外,您还需要添加以下内容:
modelBuilder.Entity<Recipe>() .HasRequired(x => x.Author) .WithMany() .WillCascadeOnDelete(false);
想法来源:EF代码优先,具有多对多自引用关系
核心是,您需要通知EF Author属性(这是一个Member实例)没有Recipe集合(用表示WithMany());这样,可以在Author属性上停止循环引用。
WithMany()
这些是从上面的“代码优先”映射创建的表:
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) );