Entity Framework Core系列教程-9-一对多关系约定

Entity Framework Core中的一对多关系约定

在上一章中,您了解了EF Core中的约定,该约定将实体映射到数据库的不同对象。在这里,您将了解两个实体类之间的关系约定,这些约定将会使数据库中对应表之间建立一对多的关系。
对于一对多关系,Entity Framework Core遵循与Entity Framework6.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; }
}

在上面的实体中应用了一对多关系的约定后,Student和Grade实体的数据库表将如下所示,其中Student表包括外键GradeId。
在这里插入图片描述

约定1

我们希望建立一对多的关系,其中许多学生与一个年级相关。可以通过在从属实体中包含引用导航属性来实现此目的,如下所示。 (此处,学生实体是从属实体,而成绩实体是主要实体)。

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; }
}

在上面的示例中,学生实体类包括班级类型的引用导航属性。这使我们可以将同一年级链接到许多不同的学生实体,从而在它们之间建立一对多的关系。这将在数据库的“学生”和“成绩”表之间产生一对多关系,其中“学生”表包含可为空的外键GradeId,如下所示。 EF Core将为概念模型中名为GradeId的外键创建一个阴影属性,该属性将映射到Students表中的GradeId外键列。
注意:引用属性Grade是可为空的,因此它将在Student表中创建可为空的ForeignKey GradeId。您可以使用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 ICollection<Student> Students { get; set; } 
}

在上面的示例中,“Grade”实体包括类型为ICollection<student>的集合导航属性。这将使我们能够向班级实体添加多个“学生”实体,从而导致数据库中“学生”和“班级”表之间存在一对多的关系,与约定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 ICollection<Student> Students { get; set; }
}

在上面的示例中,学生实体包括班级类型的引用导航属性,班级实体类包括集合导航属性ICollection<Student>,这导致相应的数据库表“学生”和“成绩”之间存在一对多关系,与约定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 ICollection<Student> Students { get; set; }
}

在上面的示例中,Student实体包括类型为int的外键属性GradeId及其引用导航属性Grade。在另一端,成绩实体还包括一个集合导航属性ICollection<Student>.。这将与Student表中的NotNull外键列建立一对多关系,如下所示。
在这里插入图片描述
如果要将外键GradeId设置为可为空,则使用可为null的int数据类型(Nullable<int>或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来配置一对多关系。

posted @ 2020-02-07 21:47  星空天宇  阅读(190)  评论(0编辑  收藏  举报