I'm trying to map some enums in my model to PostgreSQL custom enum types using EF Core, but no matter what I do, EF Core keeps sending the values as integers instead of using the PostgreSQL enum type.
Enum definition:
public enum EventType
{
Purchase,
Signup,
OfferTrading
}
DbContext configuration:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
modelBuilder.HasPostgresEnum<EventType>(
name: "event_type",
nameTranslator: new NpgsqlSnakeCaseNameTranslator());
// also tried:
// modelBuilder.HasPostgresEnum<EventType>("event_type");
// modelBuilder.HasPostgresEnum<EventType>();
base.OnModelCreating(modelBuilder);
}
NpgsqlDataSource configuration:
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
dataSourceBuilder.MapEnum<EventType>(
pgName: "event_type",
nameTranslator: new NpgsqlSnakeCaseNameTranslator());
// also tried:
// dataSourceBuilder.MapEnum<EventType>("event_type");
// dataSourceBuilder.MapEnum<EventType>();
var dataSource = dataSourceBuilder.Build();
services.AddSingleton(dataSource);
services.AddDbContext<AppDbContext>((sp, options) =>
options.UseNpgsql(
sp.GetRequiredService<NpgsqlDataSource>(),
b => b.MigrationsAssembly("*******.Infrastructure"))
.UseSnakeCaseNamingConvention()
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.AddInterceptors(new AuditInterceptor()));
Design-time configuration
I also implemented IDesignTimeDbContextFactory<> with the same configuration.
Entity configuration:
builder.Property(c => c.EventType)
.HasColumnType("event_type")
.IsRequired();
I also tried adding a string converter here, but that only changes the error from integer to text. It still doesn't cast to the event_type PostgreSQL type.
Migration
From the initial migration, I can see that the enum type is created correctly (and I confirmed it exists in the database):
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:event_type", "purchase,signup,offer_trading");
And in the table definition:
event_type = table.Column<int>(type: "event_type", nullable: false),
Generated SQL
When inserting data, EF Core generates the following SQL:
INSERT INTO campaigns (id, created_at, event_type, external_template_id, name, partner_id, priority, updated_at, validity_period_end, validity_period_start, contact_channels)
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10)
Parameters:
..., @p2 = '0', ...
// should be something like:
@p2 = 'purchase' (DbType = event_type)
It is clearly not setting the parameter type to event_type. It just sends an integer value.
If I use a string converter, it sends a string instead, but still does not set the correct PostgreSQL enum type, and the error persists.
Final error
PostgresException: 42804: column "event_type" is of type event_type but expression is of type integer
Versions used:
- .NET 10
- EF Core 10
- Npgsql.EntityFrameworkCore.PostgreSQL 10.0.1
- Npgsql 10.0.2
- PostgreSQL 18
There are no global enum conversions configured (I previously had one, but removed it).
Question
What am I missing for EF Core + Npgsql to correctly bind the enum as a PostgreSQL enum type instead of sending it as integer or text?
Any help would be greatly appreciated.