使用Entity Framework Core中的Fluent API
配置一对多关系
您了解了一对多关系约定。通常,您不需要配置一对多关系,因为EF Core提供了足够的约定,可以自动配置它们。但是,如果您决定在Fluent API
中拥有所有EF配置以便于维护,则可以使用Fluent API
配置一对多关系。
Entity Framework Core使使用Fluent API
更轻松配置关系变得容易。考虑以下“学生”和“年级”类,其中“年级”实体包括许多“学生”实体。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int CurrentGradeId { 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; }
public ICollection<Student> Students { get; set; }
}
通过重写DbContext
类中的OnModelCreating
方法,使用Fluent API
为上述实体配置一对多关系,如下所示:
public class SchoolContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Database=EFCore-SchoolDB;Trusted_Connection=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasOne<Grade>(s => s.Grade)
.WithMany(g => g.Students)
.HasForeignKey(s => s.CurrentGradeId);
}
public DbSet<Grade> Grades { get; set; }
public DbSet<Student> Students { get; set; }
}
在上面的示例中,以下代码片段配置了一对多关系:
modelBuilder.Entity<Student>()
.HasOne<Grade>(s => s.Grade)
.WithMany(g => g.Students)
.HasForeignKey(s => s.CurrentGradeId);
现在,要将其反映在数据库中,请执行迁移命令,add-migration <名称>
和update-database
。该数据库将包括两个具有一对多关系的表,如下所示。
让我们逐步解析上面的代码。
首先,我们需要开始使用一个实体类(学生或年级)进行配置。因此,modelBuilder.Entity<student>()
从Student
实体开始。
然后,.HasOne<Grade>(s => s.Grade)
指定Student
实体包括一个名为Grade
的班级类型属性。
现在,我们需要配置关系的另一端,班级实体。 .WithMany(g => g.Students)
指定班级实体类包括许多学生实体。在这里,WithMany
推断集合导航属性。
.HasForeignKey<int>(s => s.CurrentGradeId)
指定外键属性CurrentGradeId
的名称。这是可选的。仅当在依赖类中具有外键ID
属性时,才使用它。
下图说明了上述步骤:
或者,您可以一开始配置班级实体而不是学生实体的关系,如下所示。
modelBuilder.Entity<Grade>()
.HasMany<Student>(g => g.Students)
.WithOne(s => s.Grade)
.HasForeignKey(s => s.CurrentGradeId);
使用Fluent API配置级联删除
当相关的父行被删除时,级联删除会自动删除子行。例如,如果删除了一个班级,则该班级中的所有学生也应自动从数据库中删除。
使用OnDelete
方法来配置Student
和Grade
实体之间的级联删除,如下所示:
modelBuilder.Entity<Grade>()
.HasMany<Student>(g => g.Students)
.WithOne(s => s.Grade)
.HasForeignKey(s => s.CurrentGradeId)
.OnDelete(DeleteBehavior.Cascade);
OnDelete()
方法使用DeleteBehavior
参数定义级联删除行为。您可以根据需要指定以下任何DeleteBehavior
值。
Cascade
: 删除主体实体时,从属实体也会被删除。ClientSetNull
: 相关实体中外键属性的值将设置为null
。Restrict
: 防止级联删除。SetNull
: 相关实体中外键属性的值将设置为null
。