在上一章中,您了解了将实体映射到数据库的不同对象的EF约定。在这里,您将了解两个实体类之间的关系约定,这些约定会导致数据库中相应表之间的一对多关系。
Entity Framework Core 遵循与 Entity Framework 6.x相同的约定,用于一对多关系。唯一的区别是EF Core创建了一个与导航属性名称相同的外键列,而不是<NavigationPropertyName>_<PrimaryKeyPropertyName>
让我们来看看不同的约定自动配置以下之间的一个一对多的关系Student
和Grade
实体。
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
}
public class Grade
{
public int GradeId { get; set; }
public string GradeName { get; set; }
public string Section { get; set; }
}
在上述实体中应用一对多关系的约定后,for Student
和Grade
entities 的数据库表将如下所示,其中Students
表包含外键GradeId
。
约定 1
我们希望建立一对多的关系,许多学生与一个年级相关联。这可以通过在从属实体中包括引用导航属性来实现,如下所示。(此处,Student
实体是从属实体,Grade
实体是主体)。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public Grade Grade { get; set; }
}
public class Grade
{
public int GradeId { get; set; }
public string GradeName { get; set; }
public string Section { get; set; }
}
在上面的示例中,Student
实体类包括Grade
类型的引用导航属性。这允许我们将它们链接Grade
到许多不同的Student
实体,这在它们之间创建了一对多的关系。这将在数据库中的表Students
和Grades
表之间产生一对多的关系,其中Students
table包含可以为空的外键GradeId
,如下所示。EF Core将为GradeId
概念模型中指定的外键创建一个shadow属性,该外键将映射到表中的GradeId
外键列Students
。
注意:引用属性Grade
是可空的,因此它GradeId
在Students
表中创建一个可为空的ForeignKey 。您可以使用Fluent API配置NotNull外键。
约定 2
另一个约定是在主体实体中包含集合导航属性,如下所示。
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
}
public class Grade
{
public int GradeId { get; set; }
public string GradeName { get; set; }
public string Section { get; set; }
public List<Student> Students { get; set; }
}
在上面的示例中,Grade
实体包含类型的集合导航属性List<student>
。这将允许我们向Student
实体添加多个Grade
实体,这导致数据库中的表Students
与Grades
表之间的一对多关系,与约定1中的相同。
约定 3
一对多关系的另一个EF约定是在两端包含导航属性,这也将导致一对多关系(约定1 +约定2)。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public Grade Grade { get; set; }
}
public class Grade
{
public int GradeID { get; set; }
public string GradeName { get; set; }
public List<Student> Students { get; set; }
}
在上面的例子中,Student
实体包括的参考导航属性Grade
类型和Grade
实体类包括收集导航属性List<Student>
,这导致相应的数据库中的表之间的一对多的关系Students
和Grades
,与约定1相同。
约定 4
使用从属实体中的外键属性在两端完全定义关系会创建一对多关系。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int GradeId { get; set; }
public Grade Grade { get; set; }
}
public class Grade
{
public int GradeId { get; set; }
public string GradeName { get; set; }
public List<Student> Students { get; set; }
}
在上面的示例中,Student
实体包括GradeId
类型的外键属性int
及其引用导航属性Grade
。在另一端,Grade
实体还包括集合导航属性List<Student>
。这将与表中的NotNull外键列创建一对多关系Students
,如下所示。
如果要将外键设置GradeId
为可为空,则使用nullable int data type(Nullable<int> or int?
),如下所示。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int? GradeId { get; set; }
public Grade Grade { get; set; }
}
因此,这些是在相应的数据库表中自动创建一对多关系的约定。如果实体不遵循上述约定,则可以使用Fluent API配置一对多关系。