EntityFrameworkCore是否有一种方法可以创建EnumToStringConverter而不将枚举类型作为泛型传递?

时间:2018-06-15 17:26:18

标签: c# reflection entity entity-framework-core valueconverter

我正在尝试使用EntityFrameworkCore ORM与我的数据库进行交互。默认情况下,EntityFrameworkCore似乎将枚举存储为int而不是字符串。

但是,我想将值作为字符串存储在数据库中。我可以看到EntityFrameworkCore附带了一个名为EnumToStringConverter的转换器。

我正在尝试使用反射来设置模型构建器,因此我不必手动构建每个模型。

我遇到的问题是EnumToStringConverter接受一个必须是enum的泛型类型。但由于我在这里尝试使用反射,因此在创建转换器时无法传递枚举类型

这是我的代码到目前为止的样子

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // Get all DbSet<> properties that are defined in the DbContext
    var modelTypes = typeof(DataContext).GetProperties()
                                        .Where(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
                                        .Select(x => x.PropertyType.GetGenericArguments().First())
                                        .ToList();

    foreach (Type modelType in modelTypes)
    {
        var properties = modelType.GetProperties();

        foreach (var property in properties)
        {
            if (IsPrimaryKey(property))
            {
                // At this point we know that the property is a primary key
                modelBuilder.Entity(modelType)
                            .Property(property.Name)
                            .UseSqlServerIdentityColumn()
                            .Metadata.BeforeSaveBehavior = PropertySaveBehavior.Ignore;

                continue;
            }

            if (property.PropertyType.IsEnum)
            {
                // At this point we know that the property is an enum.
                // Add the EnumToStringConverter converter to the property so that
                // the value is stored in the database as a string instead of number 
                var converter = new EnumToStringConverter(); // if somehow I can change this code to something like var `new EnumToStringConverter(property.PropertyType);` the code would work

                modelBuilder.Entity(modelType)
                            .Property(property.Name)
                            .HasConversion(converter);

                continue;
            }

        }
    }
}

上述代码的唯一问题是如何构造EnumToStringConverter。如果我以某种方式向Type的构造函数提供EnumToStringConverter,而不是将其作为通用参数传递来解决问题。

2 个答案:

答案 0 :(得分:3)

Pre-defined conversions文档部分所述:

  

对于存在内置转换器的常见转换,无需明确指定转换器。相反,只需配置应使用哪种提供程序类型,EF将自动使用适当的内置转换器。以上使用枚举字符串转换作为示例,但如果配置了提供程序类型,EF实际上会自动执行此操作:

然后是一个例子。

然后,你可以简单地使用:

{{1}}

答案 1 :(得分:1)

一直在寻找相同的东西,但不想使用流利的方法。

将以下内容放入枚举属性。

 [Column(TypeName = "nvarchar(32)")] 

这将自动将其另存为字符串。如果放在基类中,则适用于所有派生实体。

您还可以注册类型配置

public class BaseEntityTypeConfiguration : IEntityTypeConfiguration<BaseEntity>
{
    public void Configure(EntityTypeBuilder<BaseEntity> builder)
    {
        builder.Property(p => p.YourEnumProp).HasConversion<string>();
    }
}

然后将其注册到modelBuilder

mb.ApplyConfiguration(new BaseEntityTypeConfiguration());