Many-to-Many & One-to-Many (EF) - 代码优先
Many-to-Many & One-to-Many (EF) - Code First
正在为 school-type 系统创建 code-first 数据库。
我遇到的问题是课程和用户部分。
用户
- 可以选修很多课程
- 可以教授多门课程
课程
- 可以有很多用户
- 只能有 1 位老师
以下是我的课程和用户的 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);
注意:在上面的示例中,如果我所做的与您的意思不符,您可能需要交换 Running
和 Taking
映射。
更新: 我几乎总是忘记,两个实体之间存在不止一种关系会导致著名的 多级联路径 错误。所以你需要关闭级联删除,它只能用 fluent API 来完成,因此数据注释不是一个选项。
正在为 school-type 系统创建 code-first 数据库。
我遇到的问题是课程和用户部分。
用户
- 可以选修很多课程
- 可以教授多门课程
课程
- 可以有很多用户
- 只能有 1 位老师
以下是我的课程和用户的 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);
注意:在上面的示例中,如果我所做的与您的意思不符,您可能需要交换 Running
和 Taking
映射。
更新: 我几乎总是忘记,两个实体之间存在不止一种关系会导致著名的 多级联路径 错误。所以你需要关闭级联删除,它只能用 fluent API 来完成,因此数据注释不是一个选项。