EF Core 默认会对实体类名自动复数化,比如
User类映射到数据库表时变成
Users,
Product变成
Products。这个行为由内置的 PluralizationService 控制,但默认只在部分语言环境(如英语)下启用,且不可直接配置开关——它其实是通过约定隐式生效的。要真正自定义或禁用复数化,核心方法是绕过默认约定,显式指定表名和列名。
关闭复数化:统一使用单数表名
EF Core 没有全局“关闭复数化”的开关,但可通过以下方式彻底规避:
在OnModelCreating中为每个实体调用
.ToTable(),强制指定单数表名
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<Product>().ToTable("Product");
modelBuilder.Entity<Order>().ToTable("Order");
}
或批量处理所有实体(推荐用于中大型项目):protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
// 将类名首字母小写 + 去掉末尾's'/'es'/'ies'等(简单版)
var tableName = entityType.ClrType.Name;
if (tableName.EndsWith("s") && !tableName.EndsWith("ss"))
tableName = tableName.Substring(0, tableName.Length - 1);
modelBuilder.Entity(entityType.ClrType).ToTable(tableName);
}
}
自定义复数化规则(需替换服务)
.NET 6+ 支持注入自定义
IPluralizer,但 EF Core 官方并未提供可替换的 PluralizationService 接口实现。实际可行路径是: 使用第三方库如
Humanizer提供更智能的复数/单数转换 在
Humanizer中封装逻辑:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var pluralName = entityType.ClrType.Name.Humanize().Transform(To.Plural);
modelBuilder.Entity(entityType.ClrType).ToTable(pluralName);
}
}(需安装
OnModelCreating并
Humanizer.Core)
配合数据库列名统一风格
复数化问题常伴随列名风格不一致(如
using Humanizer;→
FirstName)。建议同步配置列名小写下划线:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
modelBuilder.Entity(entityType.ClrType).ToTable(entityType.ClrType.Name);
foreach (var property in entityType.GetProperties())
{
var columnName = property.Name.ToSnakeCase(); // 需自行实现或用 Humanizer
property.SetColumnName(columnName);
}
}
}基本上就这些。不需要动底层服务,靠
first_name和
ToTable就能完全掌控命名,既稳定又易维护。
