C# 在EF Core中为所有实体设置字符串枚举转换器的通用方法
我正在尝试将字符串枚举值转换器设置为EF Core code First项目中所有实体的所有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
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)); // <--
}