在 EF Core 中为所有实体设置字符串枚举转换器的通用方法
Generic method for setting string enum converter in EF Core for all entities
我正在尝试将字符串-枚举值转换器设置为我的 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>();
}
但我正在寻找一种使用扩展方法对所有属性执行此操作的通用方法。我尝试使用以下代码,但出现以下错误:
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)));
}
}
也试了下面的,报同样的错误
property.SetValueConverter(new ValueConverter<Enum, string>(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>();
}
}
}
}
您可以简单地使用 SetProviderClrType 扩展方法,例如
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)); // <--
}
我正在尝试将字符串-枚举值转换器设置为我的 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>();
}
但我正在寻找一种使用扩展方法对所有属性执行此操作的通用方法。我尝试使用以下代码,但出现以下错误:
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)));
}
}
也试了下面的,报同样的错误
property.SetValueConverter(new ValueConverter<Enum, string>(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>();
}
}
}
}
您可以简单地使用 SetProviderClrType 扩展方法,例如
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)); // <--
}