-
Notifications
You must be signed in to change notification settings - Fork 877
Description
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.
Reactions are currently unavailable