ASP.NET MVC 多对多关系,使用 "My Own" table

ASP.NET MVC Many to Many relationship, using "My Own" table

我对 entity framework 使用 Code First 方法还很陌生,我知道我与下面的实体有很多对多的关系,EF 会自动创建中介 table:

class Post {
  ...
  public virtual ICollection<Category> Categories {get; set;}
  ... 
}

class Category {
   ...
   public virtual ICollection<Post> Posts {get; set;}
   ...
}

但是,如果在中介 table 中我需要额外的数据字段,一种可能的方式(我目前喜欢,可能是因为我不知道更好的方式)是定义我的新实体拥有,例如:

class Posts_Categories {
   public int Id {get; set;}
   public int CategoryId {get; set;}
   public int PostId {get; set;}
   public string Exrtafield1 {get; set;}
   public int ex extraField2 {get; set;}
   ...
   public virtual Post Post {get; set;}
   public virtual Category Category {get; set;}
}

使用这种方法,EF 确实创建了我的自定义中介 table,但它也创建了另一个自己的中介 "PostsCategories",它只包含 Post_Id 的外键和另一个至 Category_Id.

如何让它不创建额外的那个而使用我定义的那个? 这是管理带有额外数据字段的多对多关系的好方法吗??

为两者之间的关系创建 PostsCategories table 是正常的,您将需要它。如果 c 是类别,您将能够执行 c.Posts

之类的操作

通常您不会为此手动创建自己的 table。您会在 "extra" 字段中保留哪些类型的数据?我可能会将字段移动到其他 table 之一并删除那个。大多数多对多关系 table 不包含额外字段。

你应该像这样使用一对多关系:

public class Post
{
    public System.Int32 PostId { get; set; }

    [InverseProperty("Post")]
    public virtual ICollection<Posts_Category> PostCategories { get; set; }
}

public class Category
{
    public System.Int32 CategoryId { get; set; }

    [InverseProperty("Category")]
    public virtual ICollection<Posts_Category> PostCategories { get; set; }
}

public class Posts_Category
{
    public System.Int32 PostId { get; set; }

    public System.Int32 CategoryId { get; set; }

    [ForeignKey("PostId")]
    [InverseProperty("PostCategories")]
    public virtual Post Post { get; set; }

    [ForeignKey("CategoryId")]
    [InverseProperty("PostCategories")]
    public virtual Category Category { get; set; }
}

我需要对 Iraj 的回答进行一些扩展才能使其生效。另一个修改是我将默认 ApplicationUser 作为我的表格之一。

所以关系是ApplicationUser 1-∞ IdeaVote ∞-1 Idea(即有用户和想法,用户可以对想法进行投票,每次投票用ApplicationUserIdea 之间的联系。

public class Idea
{
    [Key]
    public int Id { get; set; }

    // This is an ordinary data field
    public string Text { get; set; }

    [InverseProperty("Idea")]
    public virtual ICollection<IdeaVote> Votes { get; set; }
}

public class IdeaVote
{
    [Key]
    public int Id { get; set; }

    public int IdeaId { get; set; }
    [ForeignKey("IdeaId")]
    [InverseProperty("Votes")]
    public virtual Idea Idea { get; set; }

    public string UserId { get; set; }
    [ForeignKey("UserId")]
    [InverseProperty("Votes")]
    public virtual ApplicationUser User { get; set; }
}
public class ApplicationUser : IdentityUser
{
    [InverseProperty("User")]
    public virtual ICollection<IdeaVote> Votes { get; set; }

    // Default stuff
}