实体框架 - 关系
在关系数据库中,关系是通过外键存在于关系数据库表之间的一种情况。外键 (FK) 是用于建立和加强两个表中的数据之间的链接的一列或多列组合。下图包含三个表。
- Student 学生
- Course 课程
- Enrollment 注册
在上图中,您可以看到表之间的某种关联/关系。表之间存在三种类型的关系,不同表之间的关系取决于相关列的定义方式。
- 一对多关系
- 多对多关系
- 一对一关系
一对多关系
一对多关系是最常见的关系类型。
在这种类型的关系中,表 A 中的一行可以与表 B 中的多行匹配,但表 B 中的一行只能与表 A 中的一行匹配。
外键在代表关系多端的表中定义。
例如,在上图中,Student 和 Enrollment 表具有一对多关系,每个学生可能有许多注册,但每个注册只属于一个学生。
在实体框架中,这些关系也可以用代码创建。以下是与一对多关系相关联的 Student 和 Enrollment 类的示例。
public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } }
在上面的代码中,你可以看到 Student 类包含 Enrollment 的集合,但是 Enrollment 类只有一个 Student 对象。
多对多关系
在多对多关系中,表 A 中的一行可以与表 B 中的多行匹配,反之亦然。
你可以通过定义第三个表(称为连接表)来创建这种关系,该表的主键由表 A 和表 B 的外键组成。
例如,Student 和 Course 表具有多对多关系,该关系由每个表与 Enrollment 表的一对多关系定义。
以下代码包含 Course 类和上述两个类,即 Student 和 Enrollment。
public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } }
您可以看到 Course 类和 Student 类都具有 Enrollment 对象集合,通过连接类 Enrollment 建立了多对多关系。
一对一关系
在一对一关系中,表 A 中的一行在表 B 中最多只能有一行匹配,反之亦然。
如果两个相关列都是主键或具有唯一约束,则创建一对一关系。
在一对一关系中,主键还充当外键,并且两个表都没有单独的外键列。
这种类型的关系并不常见,因为以这种方式关联的大多数信息都位于一个表中。您可以使用一对一关系来减去
- 用许多列划分表格。
- 出于安全原因隔离表格的一部分。
- 存储短暂的数据,只需删除表格即可轻松删除这些数据。
- 存储仅适用于主表子集的信息。
以下代码用于添加另一个类名 StudentProfile,其中包含学生电子邮件 ID 和密码。
public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } public virtual StudentProfile StudentProfile { get; set; } } public class StudentProfile { public StudentProfile() {} public int ID { get; set; } public string Email { get; set; } public string Password { get; set; } public virtual Student Student { get; set; } }
您可以看到 Student 实体类包含 StudentProfile 导航属性,StudentProfile 包含 Student 导航属性。
每个学生只有一个电子邮件和密码来登录大学域。这些信息可以添加到 Student 表中,但出于安全原因,它被分离到另一个表中。