在 EFCore 中,每个实体都是在实现 IEntityTypeConfiguration 接口的类里配置的,IEntityTypeConfiguration 是泛型接口,需要传入实体类,并且实现 Configure 方法,而 Configure 方法有一个 EntityTypeBuilder<T> 参数,用于对该实体进行配置。实体配置一般分为两种,一种是对实体本身的配置,一种是对实体属性的配置。一般情况下,实体本身会映射到数据库的一张表,而实体的属性会映射到表中的数据列。

实体本身由 EntityTypeBuilder 直接配置,下面介绍常用的几个配置。

  • ToTable 方法:用于配置生成数据库的表名。如果未指定,则默认与 DbSet 的名字相同。
  • HasKey 方法:用于配置表的主键。如果未指定,则默认以 Id 属性或者 [TypeName]Id 属性(其中 [TypeName] 为实体类名)为主键。
  • HasIndex 方法:用于配置表的索引。
  • Ignore 方法:用于排除实体的属性,使其在生成数据库时被忽视。

上面的方法中,ToTable 和 Ignore 会返回 EntityTypeBuilder 自身,所以可以继续链式调用。但是 HasKey 会返回 KeyBuilder,而 HasIndex 会返回 IndexBuilder,这两个类用于继续对主键或索引继续配置。例如 Index.Builder 的 IsUnique 方法和 IsClustered 方法分别用于配置索引是否为唯一索引、是否为聚集索引。

例如下面的代码将表名设置为 T_Books,并且将 Id 属性设置为主键,将 Title 属性设置为唯一索引,并将在生成数据库时排除 Time 属性。

public void Configure(EntityTypeBuilder<Book> builder)
{
    builder.ToTable("T_Books").HasKey(e => e.Id).Ignore(e => e.Time);
    builder.HasIndex(e => e.Title).IsUnique();
}

到这里可以看出,EFCore 的配置类其实都是类似的 Builder 模式。不同的 Builder 对不同的东西进行配置。如果需要对实体的属性进行配置,那么就需要获取 PropertyBuilder,通过 EntityTypeBuilder.Property 方法可以获取指定的属性:

var titleBuilder =  builder.Property(e => e.Title);

之后便可以使用 PropertyBuilder 对属性进行配置了。下面介绍常用的配置:

  • HasColumnName 方法:用于配置列名。
  • HasColumnType 方法:用于配置列类型。
  • HasMaxLength 方法:用于配置列最大宽度。
  • IsUnicode 方法:用于配置列是否采用 Unicode 编码。
  • IsRequired 方法:用于配置列是否不可为空。

下面这行代码,设置 Title 列具有 50 的最大长度,采用 Unicode 编码并不可为空。

builder.Property(e => e.Title).HasMaxLength(50).IsRequired().IsUnicode();

除了上面所说的,在 DbContext 类中的 OnModelCreating 方法,可以在更高层面对数据库映射进行配置,例如排除实体映射:

modelBuilder.Ignore<Book>();

其他的比如依赖注入等也是在 DbContext 类中进行配置的。