为学校类型的系统创建代码优先数据库。
我苦苦挣扎的是课程和用户部分。
用户
可以参加很多课程
可以教多门课程
课程
可以有很多用户
只能有一位老师
以下是我的课程和用户的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类中有2个收藏集,然后Course课程中有2个收藏集。
我想我必须在虚拟属性上设置外键属性,但是我不确定。
尝试搜索了最近几个小时,但找不到符合此需求的任何内容。
谢谢
最佳答案
您所需要做的就是映射定义每个关系的相应导航属性。
如果您喜欢数据注释,则可以使用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
映射。更新:我几乎总是忘记,两个实体之间存在多个关系会导致著名的多个级联路径错误。因此,您需要关闭级联删除,并且只能使用流利的API来完成,因此不能使用数据注释。