Я пытаюсь найти общее решение проблемы перечислений с EF 4.1. Мое решение в основном является общей версией Как подделать перечисления в ef 4 . Класс-оболочка enum прекрасно работает в остальной части кода и допускает такой код:
EnumWrapper<Color> c = Color.Red;
Вот класс-обертка enum:
public class EnumWrapper<TEnum> where TEnum : struct, IConvertible
{
public EnumWrapper()
{
if (!typeof(TEnum).IsEnum)
throw new ArgumentException("Not an enum");
}
public TEnum Enum { get; set; }
public int Value
{
get { return Convert.ToInt32(Enum); }
set { Enum = (TEnum)(object)value; }
}
public static implicit operator TEnum(EnumWrapper<TEnum> w)
{
if (w == null) return default(TEnum);
else return w.Enum;
}
public static implicit operator EnumWrapper<TEnum>(TEnum e)
{
return new EnumWrapper<TEnum>() { Enum = e };
}
public static implicit operator int(EnumWrapper<TEnum> w)
{
if (w == null)
return Convert.ToInt32(default(TEnum));
else
return w.Value;
}
}
перечисление:
public enum Color { red = 1, green = 2, blue = 3 }
ПОКО:
public class ChickenSandwich
{
public ChickenSandwich() {
CheeseColor = new EnumWrapper<Color>();
}
public int ID { get; set; }
public string Name { get; set; }
public EnumWrapper<Color> CheeseColor { get; set; }
}
Отображение:
public class ColorMapping : ComplexTypeConfiguration<EnumWrapper<Color>>
{
public ColorMapping() {
Ignore(x => x.Enum);
Property(x => x.Value);
}
}
Я также попытался сопоставить его с конфигурацией EntityType в ChickenSandwich следующим образом:
Property(x => x.CheeseColor.Value).HasColumnName("CheeseColor");
Если я оставлю это до ColorMapping и не сделаю явного отображения на ChickenSandwichMapping, оно просто не поместит его в базу данных. Если я сопоставлю это способом x.CheeseColor.Value, я получу ужас:
System.InvalidOperationException:
настроенное свойство 'CheeseColor'
не объявленная собственность на юридическом лице
'Куриный сендвич'. Убедитесь, что он имеет
не был явно исключен из
модель и что это действительный примитив
свойство ..
Редактировать
Мне не удалось заставить работать универсальную версию оболочки enum, поэтому я перешел к написанию отдельных оболочек. Это не совсем то, что я хотел, потому что он нарушает принцип DRY , но он позволяет запрашивать столбец как перечисление.
[ComplexType]
public class ColorWrapper
{
[NotMapped]
public Color Enum { get; set; }
public int Value
{
get { return (int)Enum; }
set { Enum = (Color)value; }
}
public static implicit operator Color(ColorWrapper w)
{
if (w == null) return default(Color);
return w.Enum;
}
public static implicit operator ColorWrapper(Color c)
{
return new ColorWrapper { Enum = c };
}
}
Мне пришлось использовать ColorWrapper в классе ChickenSandwich. Работает более-менее прозрачно. Затем пришлось добавить это в мой конструктор класса отображения, чтобы получить имя столбца, который я хотел:
Property(x => x.CheeseColor.Value).HasColumnName("CheeseColorId");