Entity Framework Core-使用Fluent API配置一对多关系

EF Core 通过使用Fluent API在两个实体间创建一对多关系,这节使用Has/With模式来配置表之间的关系
Has模式有两个方法,分别是HasOne()和HasMany()方法,With模式也有两个方法,分别是WithOne()和WithMany()方法,我们能使用下面两者中的任何一个来创建关系.
HasOne – WithMany
HasMany – WithOne

1 例子: Fluent API 一对多关系

下面使用Country和City实体

public class Country{    public int Id { get; set; }    public string Name { get; set; }    public ICollection<City> City { get; set; }}public class City{    public int Id { get; set; }      public string Name { get; set; }    public int FKCountry { get; set; }    public Country Country { get; set; }}
Country实体有一个集合的导航属性City
public ICollection<City> City { get; set; }
City有一个引用导航属性Country
public Country Country { get; set; }
我们在DbContext的OnModelCreating 方法内使用Fluent API 创建一个一对多的关系,如下所示
public class CountryContext: DbContext{    public DbSet<City> City { get; set; }    public DbSet<Country> Country { get; set; }    public CountryContext(DbContextOptions<CountryContext> options) : base(options)    {    }    protected override void OnModelCreating(ModelBuilder modelBuilder)    {        //Write Fluent API configurations here        modelBuilder.Entity<City>()                    .HasOne(e => e.Country)                    .WithMany(e => e.City)                    .HasForeignKey(e => e.FKCountry)                    .OnDelete(DeleteBehavior.Cascade); ;    }}

运行EF Core migration 能够在数据库表中获取Country和City,并且在City表中创建了一个PKCountry的外键

2 理解一对多关系配置

我们开始配置Country或者City任何一个实体,配置City实体类modelBuilder.Entity<City>

接下来我们使用Has/With模式,通过使用.HasOne(e => e.Country)方法,我们指定City实体类引用导航属性Country,在他们之间将创建一个一对多的关系

接着我们使用.WithMany(e => e.City)方法指定Country实体包含多个City的导航属性

.HasForeignKey(e => e.FKCountry)针对数据库City表创建了一个名为FKCountry的外键属性

在上面代码中,我们也能使用HasOne-WithMany在City和Country实体创建一对多的关系
你也可以使用HasMany – WithOne模式配置一对多关系通过,在这种情况下我们以Country 实体类开始来配置关系:
modelBuilder.Entity<Country>()            .HasMany(e => e.City)            .WithOne(e=>e.Country)            .HasForeignKey(e => e.FKCountry);

3 使用Fluent API做级联删除

删除外键父元素时EF Core有不同的行为,我们使用Fluent API来配置该行为,如果父元素的行被删除时可以指定EF Core 删除对应的子元素数据,或者设置外键为空,或者阻止删除

使用.OnDelete()方法来完成
在上面代码中我们设置DeleteBehaviour属性为级联删除,意味着当父元素被删除时依赖的实体数据也会被删除
modelBuilder.Entity<City>()            .HasOne(e => e.Country)            .WithMany(e => e.City)            .HasForeignKey(e => e.FKCountry)            .OnDelete(DeleteBehavior.Cascade); //Cascade behaviour

DeleteBehaviour有4个值

1 Cascade:如果主表数据被删除时,字表中关联的数据也会被删除

2 ClientSetNull:如果主表数据被删除时,子表中对应的外键值设置为null

3 Restrict:阻止级联删除

4 SetNull:如果主表数据被删除时,子表中对应的外键值设置为null

4 级联删除例子

我们在数据库City和Country表有部分数据,如下图显示

Entity Framework Core-使用Fluent API配置一对多关系

Entity Framework Core-使用Fluent API配置一对多关系

我们通过EF Core删除Country为"1"的数据:
Country country = new Country(){    Id = 1};context.Remove(country);await context.SaveChangesAsync();

设置为级联删除后,所有City关联的Country为1的数据将会被自动删除,下面图片显示了这两张表执行完删除之后的结果

Entity Framework Core-使用Fluent API配置一对多关系

Entity Framework Core-使用Fluent API配置一对多关系

总结
这节我们主要介绍了在EF Core中使用Fluent API配置一对多关系
源代码地址
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/EntityFrameworkCore/EFCoreFluentAPIOneToMany