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

时间:2011-12-30 09:02:10

标签: c# generics frameworks enums 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; }
}

目的是让枚举在数据库中作为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();
    }
}

1 个答案:

答案 0 :(得分:4)

正如sinelaw已经指出的那样,EF5明确支持Enums,但如果由于某种原因无法迁移到它,我采取的方法可能对你有用。

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

public enum EmailPriorityEnum
{
    Now = 100,
    Soon = 1000,
    Whenever = 10000
}

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

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

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

  1. 您必须小心,所有可能的值都使用正确的ID映射到枚举中。对于经常更改的枚举,这会产生问题。
  2. 开发人员仍然可以访问基础列,除非您更改了可访问性,并且可以想象地绕过枚举并使用他们喜欢的任何值。