EF Core 默认支持枚举类型映射,但行为取决于版本和配置方式。从 EF Core 5.0 起,枚举可直接作为属性使用,无需中间字段;但若想控制存储格式(比如存为字符串而非数字)、避免类型不匹配或适配现有数据库规范,仍需主动配置。
直接映射(EF Core 5.0+ 推荐)
只要枚举基础类型与数据库字段兼容(如
enum Status : byte对应
TINYINT),且数据库字段类型匹配,EF Core 会自动处理读写: 定义枚举时建议显式指定基础类型(
byte、
int或
short),避免默认
int导致字段过大 实体中直接声明枚举属性即可:
public OrderStatus Status { get; set; }
迁移生成的列类型会自动对应(如 byte→
TINYINT,
int→
INT)
映射为字符串(提升可读性)
存为
VARCHAR可让数据库直接显示枚举名称(如
'Pending'),方便排查和 SQL 查询: 在
OnModelCreating中配置转换器:
builder.Property(e => e.Status).HasConversion<string>()</string>该方式使用内置字符串转换器,自动调用
ToString()和
Enum.Parse注意:数据库字段需设为足够长度的字符串类型(如
NVARCHAR(20)),否则可能截断
自定义转换器(应对特殊场景)
当默认转换不满足需求时,可编写值转换器,例如处理 JSON 字段中的枚举、可空枚举或大小写/别名映射:
可空枚举必须用泛型转换器:new EnumToNumberConverter<orderstatus int>()</orderstatus>JSON 字段中嵌套枚举,需确保转换器与
System.Text.Json行为一致 自定义字符串映射(如把
Pending存为
'PND')可继承
ValueConverter<tenum string></tenum>并重写构造逻辑
避坑要点
常见问题多源于类型不匹配或忽略空值,实际开发中要注意:
枚举基础类型(: long)和转换目标类型(
.HasConversion<int>()</int>)必须一致,否则运行时报错 数据库字段允许 NULL 时,枚举属性应声明为可空(
Status?),并配对使用可空转换器 迁移生成的类型名默认小写+蛇形(如
orderstatus),若需 PascalCase,应显式用
HasColumnType("VARCHAR(20)") 控制
基本上就这些。核心是:简单场景直接用,要可读就转字符串,有特殊逻辑就写转换器——不复杂但容易忽略细节。
