Entity Framework - Общие перечисления? - PullRequest
6 голосов
/ 30 декабря 2011

Попытка создать обходной путь для обработки Enums в Entity Framework с использованием Generics, но 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?

Цель состоит в том, чтобы сделать вещи общими, поскольку у меня есть около двух десятков перечислений, которые необходимо сохранить, и я бы не стал писать отдельные классы-оболочки для каждого из них.

Вот обобщенный класс EnumWrapper, который демонстрирует, чего я хотел бы достичь: неявное преобразование в enum, но постоянство как 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 Ответ

4 голосов
/ 18 октября 2012

Как уже указывал sinelaw, EF5 имеет явную поддержку Enums, но если по какой-либо причине вы не можете перейти на него, то выбранный мною подход может сработать для вас.

Для этого примера, скажем, таблица называется «Электронная почта», и у нас есть столбец с именем «Приоритет». Настройте ваш столбец как 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. Вы должны быть осторожны, чтобы все возможные значения отображались в перечислении с соответствующими идентификаторами. Для часто меняющихся перечислений это становится проблематичным.
  2. Разработчики по-прежнему будут иметь доступ к нижележащему столбцу, если вы не измените доступность и, возможно, сможете обойти перечисления и использовать любое значение, которое им нравится.
...