Таблица сопоставления "многие ко многим"
из примеров, которые я видел в интернете и в программировании Entity Framework CodeFirst book, когда у вас есть коллекция для обоих классов, EF создаст таблицу сопоставления, такую как MembersRecipes
и первичный ключ от каждого класса будет ссылаться на эту таблицу.
однако, когда я делаю ниже, я вместо этого получаю новое поле в Recipes
стол Member_Id
и Recipe_Id
на Members
таблица.
который создает только два отношения "один ко многим", но не a многие ко многим, поэтому я мог бы иметь член 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; }
}
обновление:
Ниже приведен другой подход, который я пробовал, который не использует Fluent API и заменяет AuthorId
& Author
on 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; }
1 ответ:
сделайте это на вашем 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
обновление
чтобы предотвратить циклическую ссылку на ваше свойство автора, помимо вышеизложенного, вам нужно добавить следующее:
modelBuilder.Entity<Recipe>() .HasRequired(x => x.Author) .WithMany() .WillCascadeOnDelete(false);
идея получена здесь:код эф сперва с Много к много ссылаться собственной личности отношения
суть в том, что вам нужно сообщить EF, что свойство Author (которое является экземпляром члена) не имеет коллекций рецептов (обозначается
WithMany()
); таким образом, циклическая ссылка может быть остановлена на свойстве Author.это созданные таблицы из первых отображений кода выше:
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) );