站点图标 江湖人士

Entity Framework Core配置对象之间一对多关系

Entity Framework Core配置对象之间一对多关系

在上一章中,您了解了将实体映射到数据库的不同对象的EF约定。在这里,您将了解两个实体类之间的关系约定,这些约定会导致数据库中相应表之间的一对多关系。

Entity Framework Core  遵循与 Entity Framework 6.x相同的约定,用于一对多关系。唯一的区别是EF Core创建了一个与导航属性名称相同的外键列,而不是<NavigationPropertyName>_<PrimaryKeyPropertyName>

让我们来看看不同的约定自动配置以下之间的一个一对多的关系StudentGrade实体。

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 StudentGradeentities 的数据库表将如下所示,其中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实体,这在它们之间创建了一对多的关系。这将在数据库中的表StudentsGrades表之间产生一对多的关系,其中Studentstable包含可以为空的外键GradeId,如下所示。EF Core将为GradeId概念模型中指定的外键创建一个shadow属性,该外键将映射到表中的GradeId外键列Students

注意:引用属性Grade是可空的,因此它GradeIdStudents表中创建一个可为空的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实体,这导致数据库中的表StudentsGrades表之间的一对多关系,与约定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>,这导致相应的数据库中的表之间的一对多的关系StudentsGrades,与约定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配置一对多关系。

退出移动版