tokechu
tokechu

Reputation: 170

EF Core and PostgreSQL enum two-way name translation

I am trying to figure out how to enable two-way name translation between postgres DB and EF Core. I have found a link where it is told how values are translated from EF Core to DB, but nothing about from DB to EF Core. The problem is that when I read from DB I get values in snake case, but I need them in pascal case.

Upvotes: 1

Views: 1763

Answers (2)

VladL
VladL

Reputation: 13043

Had to research myself, just use the NpgsqlNullNameTranslator. For some reason NpgSql uses NpgsqlSnakeCaseNameTranslator as default, at least for EF Core 7.0

modelBuilder.HasPostgresEnum<MyEnum>(nameTranslator: new NpgsqlNullNameTranslator());

EDIT: in order to save them as string in DB:

modelBuilder.Entity<MyEntity>()
   .Property(u => u.EnumProperty)
   .HasConversion(new EnumToStringConverter<MyEnum>());

Upvotes: 1

devklick
devklick

Reputation: 2638

How are you reading your data from the DB?

Providing you are writing from and reading into the C# enum type that corresponds to the postgres enum type, Npgsql takes care of translating the values both ways.

For example:

Define your types:

public enum SomeDbEnum
{
    FirstValue,
    SecondValue 
}

public class SomeDbObject
{
    public SomeDbEnum DbEnum { get; set; }
}

Map your enum types

protected override void OnModelCreating(ModelBuilder builder)
    => builder.HasPostgresEnum<SomeDbEnum>();
static MyDbContext()
    => NpgsqlConnection.GlobalTypeMapper.MapEnum<SomeDbEnum>();

Try it out:

var toWriteToDb = new SomeDbObject { DbEnum = SomeDbEnum.SecondValue };
context.SomeDbObject.Add(toWriteToDb);
// value inserted as "second_value"

var readFromDb = context.SomeDbObject.FirstOrDefault(x => x.DbEnum == SomeDbEnum.SecondValue);
Console.WriteLine(readFromDb.DbEnum);
// value output as SecondValue

The same thing applies even if you use something other than the default naming translations, i.e. registered some other INpgsqlNameTranslator (other than the default NpgsqlSnakeCaseNameTranslator) or decorate your enum members with the PgNameAttribute.

Upvotes: 1

Related Questions