C# 在EF Core中为所有实体设置字符串枚举转换器的通用方法

C# 在EF Core中为所有实体设置字符串枚举转换器的通用方法,c#,enums,entity-framework-core,ef-core-3.0,valueconverter,C#,Enums,Entity Framework Core,Ef Core 3.0,Valueconverter,我正在尝试将字符串枚举值转换器设置为EF Core code First项目中所有实体的所有Enum属性 我可以这样手动执行此操作: protected override void OnModelCreating(ModelBuilder modelBuilder) { // Do this for every single enum property in each of the entities modelBuilder.Entity<M

我正在尝试将字符串枚举值转换器设置为EF Core code First项目中所有实体的所有
Enum
属性

我可以这样手动执行此操作:

    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>();
    }
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
//对每个实体中的每个枚举属性执行此操作
modelBuilder.Entity().Property(e=>e.MyEnum.HasConversion();
}
但我正在寻找一种通用方法,使用扩展方法对所有属性执行此操作。我尝试使用以下代码,但出现以下错误:

模型类型“object”的转换器不能用于“MyEnum”

公共静态void SetEnumStringConverter(此ModelBuilder ModelBuilder)
{
var properties=modelBuilder?.Model.GetEntityTypes().SelectMany(x=>x.GetProperties().Where(y=>typeof(Enum).IsAssignableFrom(y.ClrType));
foreach(属性中的var属性)
{
SetValueConverter(新的ValueConverter(v=>v.ToString(),v=>(object)Enum.Parse(property.ClrType,v));
}
}
也试过下面的,给我同样的错误

    property.SetValueConverter(new ValueConverter<Enum, string>(v => v.ToString(), v => Enum.Parse(property.ClrType, v)));
property.SetValueConverter(新的ValueConverter(v=>v.ToString(),v=>Enum.Parse(property.ClrType,v));
很明显,因为枚举不是对象


然而,还有其他通用的方法吗?

因此,经过一点挖掘,我找到了一种实现这一点的方法。虽然不是直接的,但是可以得到期望的结果

    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>();
                }
            }
        }
    }
公共静态void SetEnumStringConverter(此ModelBuilder ModelBuilder)
{
foreach(modelBuilder?.Model.GetEntityTypes()中的变量entityType)
{
var entityBuilder=modelBuilder.Entity(entityType.ClrType);
foreach(entityType.GetProperties()中的var属性)
{
if(typeof(Enum).IsAssignableFrom(property.ClrType))
{
entityBuilder.Property(Property.ClrType,Property.Name).HasConversion();
}
}
}
}
您可以简单地使用扩展方法,例如

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)); // <--
}
公共静态void SetEnumStringConverter(此ModelBuilder ModelBuilder)
{
var properties=modelBuilder.Model.GetEntityTypes()
.SelectMany(e=>e.GetProperties())
.Where(p=>(Nullable.GetUnderlyingType(p.ClrType)??p.ClrType.IsEnum);
foreach(属性中的var属性)

property.SetProviderClrType(typeof(string));//您可以使用反射来完成它。您可以找到所有模型类(假设它们共享一个命名空间),然后迭代它们的所有属性,只筛选具有枚举类型的属性,然后调用
modelBuilder.Entity().property(e=>e.MyEnum).hascoveration();
作为
MethodInfo
的一系列调用(从这里开始)如果不将框设置为
对象
,会发生什么?例如
新的值转换器(v=>v.ToString(),v=>Enum.Parse(property.ClrType,v))
@crgolden是的,我已经试过了,给我同样的error@JamesFaix是的,这就是我试图做的。只是当我使用反射时,我不能使用方法
.hascoveration()
,因为我得到的是
IMutableProperty
,而不是
PropertyBuilder
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)); // <--
}