Skip to content

Please provide non-generic methods for creating and mapping enums. #3383

@andrewslavin

Description

@andrewslavin

Currently suggested ways to create and map enums are:

ModelBuilder.HasPostgresEnum<TEnum>() //to create enum from DbContext.OnModelCreating()
NpgsqlConnection.GlobalTypeMapper.MapEnum<TEnum>() //to map enum

Can you please provide non-generic versions:

ModelBuilder.HasPostgresEnum(Type enumType)
NpgsqlConnection.GlobalTypeMapper.MapEnum(Type enumType)

This would allow to loop through properties of CLR types that represent DB entities and create+map all enums automatically, like so:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    foreach (Type enumType in
        modelBuilder.Model.GetEntityTypes()
            .SelectMany(et => et.ClrType.GetProperties().Select(pi => pi.PropertyType).Where(t => t.IsEnum)))
    {
        //create db type from enum type
        modelBuilder.HasPostgresEnum(enumType);

        //map enum type to db type
        NpgsqlConnection.GlobalTypeMapper.MapEnum(enumType);
    }
}

I have achieved the above using reflection, which looks pretty ugly:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    MethodInfo hasPostgresEnumMethodInfo = typeof(NpgsqlModelBuilderExtensions)
        .GetMethods()
        .Single(mi => mi.Name == nameof(NpgsqlModelBuilderExtensions.HasPostgresEnum) && mi.IsGenericMethod);

    INpgsqlTypeMapper typeMapper = NpgsqlConnection.GlobalTypeMapper;
    MethodInfo mapEnumMethodInfo = typeMapper.GetType().GetMethod(nameof(typeMapper.MapEnum));

    foreach (Type enumType in
        modelBuilder.Model.GetEntityTypes()
            .SelectMany(et => et.ClrType.GetProperties().Select(pi => pi.PropertyType).Where(t => t.IsEnum)))
    {
        //create db type from enum type
        hasPostgresEnumMethodInfo.MakeGenericMethod(enumType).Invoke(null, new object[] {modelBuilder, null, null, null});

        //map enum type to db type
        mapEnumMethodInfo.MakeGenericMethod(enumType).Invoke(typeMapper, new object[] {null, null});
    }
}

If there's a better way, please let me know.

Metadata

Metadata

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions