简体   繁体   中英

Generic method for setting string enum converter in EF Core for all entities

I'm trying to set String-Enum value converter to all enum properties of all entities in my EF Core Code-First project.

I can do this manually like this:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Do this for every single enum property in each of the entities
        modelBuilder.Entity<MyEntity>().Property(e => e.MyEnum).HasConversion<string>();
    }

But I'm looking for a generic way of doing this for all properties using an extension method. I tried using the below code, but I'm getting the following error:

Converter for model type 'object' cannot be used for 'MyEnum'

    public static void SetEnumStringConverter(this ModelBuilder modelBuilder)
    {
        var properties = modelBuilder?.Model.GetEntityTypes().SelectMany(x => x.GetProperties().Where(y => typeof(Enum).IsAssignableFrom(y.ClrType)));
        foreach (var property in properties)
        {
            property.SetValueConverter(new ValueConverter<object, string>(v => v.ToString(), v => (object)Enum.Parse(property.ClrType, v)));
        }
    }

Also tried the following, gives me the same error

    property.SetValueConverter(new ValueConverter<Enum, string>(v => v.ToString(), v => Enum.Parse(property.ClrType, v)));

Obviously because enum is not an object?

Nevertheless, is there any other way of doing this in a generic way?

So, after a little digging, I found a way to achieve this. Though not straightforward, gets the desired result.

    public static void SetEnumStringConverter(this ModelBuilder modelBuilder)
    {
        foreach (var entityType in modelBuilder?.Model.GetEntityTypes())
        {
            var entityBuilder = modelBuilder.Entity(entityType.ClrType);
            foreach (var property in entityType.GetProperties())
            {
                if (typeof(Enum).IsAssignableFrom(property.ClrType))
                {
                    entityBuilder.Property(property.ClrType, property.Name).HasConversion<string>();
                }
            }
        }
    }

You can simply use SetProviderClrType extension method, eg

public static void SetEnumStringConverter(this ModelBuilder modelBuilder)
{
    var properties = modelBuilder.Model.GetEntityTypes()
        .SelectMany(e => e.GetProperties())
        .Where(p => (Nullable.GetUnderlyingType(p.ClrType) ?? p.ClrType).IsEnum);

    foreach (var property in properties)
       property.SetProviderClrType(typeof(string)); // <--
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM