Many-to-Many & One-to-Many (EF) - 代码优先

Many-to-Many & One-to-Many (EF) - Code First

正在为 school-type 系统创建 code-first 数据库。

我遇到的问题是课程和用户部分。

用户

课程

以下是我的课程和用户的 2 个模型

public class User
{
  public virtual ICollection<Course> CoursesRunning { get; set; }

  public virtual ICollection<Course> CoursesTaking { get; set; }

  [DataType(DataType.Date)]
  [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
  [Required]
  public DateTime DoB { get; set; }

  [Required]
  public string EmailAddress { get; set; }

  [Required]
  public string FirstName { get; set; }

  [Required]
  public string LastName { get; set; }

  [Required]
  public string Password { get; set; }

  [Key]
  public int UserId { get; set; }

  public User()
  {
    CoursesRunning = new HashSet<Course>();
    CoursesTaking = new HashSet<Course>();
  }
}

public class Course
{
  [Key]
  public int CourseId { get; set; }

  /// <summary>
  /// The name of the course
  /// </summary>
  public string Name { get; set; }

  /// <summary>
  /// The owner of the course
  /// </summary>
  public virtual User User { get; set; }

  /// <summary>
  /// The users on the course
  /// </summary>
  public virtual ICollection<User> Users { get; set; }

  public Course()
  {
    Users = new HashSet<User>();
  }
}

如您所见,我的 User class 中有我的 2 collections,然后 [=32] 中有我的单曲和许多曲目=]课程 class.

认为我必须在我的虚拟属性上设置一个外键属性,但我真的不确定。

过去几个小时尝试搜索,但找不到符合此需求的任何内容。

谢谢

您只需映射定义每个关系的相应导航属性。

如果您更喜欢数据注释,可以使用 InverseProperty 属性,例如

public class User
{
    [InverseProperty(nameof(Course.User))]
    public virtual ICollection<Course> CoursesRunning { get; set; }

    [InverseProperty(nameof(Course.Users))]
    public virtual ICollection<Course> CoursesTaking { get; set; }
}

public class Course
{
    [InverseProperty(nameof(User.CoursesRunning))]
    public virtual User User { get; set; }

    [InverseProperty(nameof(User.CoursesTaking))]
    public virtual ICollection<User> Users { get; set; }
}

等等

或者您可以改用流畅的配置(我的首选):

modelBuilder.Entity<User>()
    .HasMany(e => e.CoursesRunning)
    .WithRequired(e => e.User)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<User>()
    .HasMany(e => e.CoursesTaking)
    .WithMany(e => e.Users);

注意:在上面的示例中,如果我所做的与您的意思不符,您可能需要交换 RunningTaking 映射。

更新: 我几乎总是忘记,两个实体之间存在不止一种关系会导致著名的 多级联路径 错误。所以你需要关闭级联删除,它只能用 fluent API 来完成,因此数据注释不是一个选项。