实体框架 - 一般地保持枚举?

Dan*_*ann 6 c# generics enums frameworks entity

尝试使用Generics创建在Entity Framework中处理Enums的变通方法,但EF似乎并不关心通用属性.例如:

public enum MyEnum
{
    One, Two, Three
}

public class SomePOCOWithEnum
{
      // I want this to persist as an int, but EF doesn't like generics.
      public EnumWrapper<MyEnum> MyEnumProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

目的是使枚举在数据库中作为INT持久存在.是否有任何特殊的方法使用流利或者其他一些机制方法,我可以创建所述泛型类并将其作为INT持久存储到EF中的数据库中?

目的是保持通用性,因为我有大约24个需要持久化的枚举,而我宁愿不为每个枚举类编写单独的包装类.

这是通用的EnumWrapper类,它演示了我想要实现的内容:隐式转换为枚举,但持久性为int:

public class EnumWrapper<T> where T : struct
{
    private T enumValue;
    public int Value
    {
        get { return Convert.ToInt32(enumValue); }
        set { enumValue = (T)Enum.Parse(typeof(T), value.ToString()); }
    }

    public T EnumValue
    {
        get { return enumValue; }
        set { enumValue = value; }
    }

    public static implicit operator T(EnumWrapper<T> wt)
    {
        return wt.EnumValue;
    }

    public static implicit operator EnumWrapper<T>(T t)
    {
        return new EnumWrapper<T>() { EnumValue = t };
    }

    public override string ToString()
    {
        return enumValue.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

Hea*_*her 4

正如 sinelaw 已经指出的那样,EF5 明确支持 Enum,但如果您出于某种原因无法迁移到它,我采取的方法可能适合您。

对于此示例,假设该表名为“Email”,并且有一列名为“Priority”。像平常一样将列设置为 int。接下来,在您的实体项目中,创建一个映射到 int 值的枚举类:

public enum EmailPriorityEnum
{
    Now = 100,
    Soon = 1000,
    Whenever = 10000
}
Run Code Online (Sandbox Code Playgroud)

最后,在您的实体项目中,创建一个与您的实体匹配的部分类文件,并在那里手动映射枚举:

public partial class Email
{
    public EmailEnums.EmailPriorityEnum EmailPriority
    {
        get { return (EmailEnums.EmailPriorityEnum)Priority; }
        set { Priority = (int)value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

从那时起,您的代码可以透明地引用此属性。这种方法的主要缺点是:

  1. 您必须小心,所有可能的值都使用正确的 id 映射到枚举中。对于经常改变的枚举来说,这会成为问题。
  2. 开发人员仍然可以访问底层列,除非您更改可访问性,并且可以绕过枚举并使用他们喜欢的任何值。