Я пытаюсь создать общее решение проблемы перечислений с 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; }
}
Mapping:
public class ColorMapping : ComplexTypeConfiguration<EnumWrapper<Color>>
{
public ColorMapping() {
Ignore(x => x.Enum);
Property(x => x.Value);
}
}
Я также попытался сопоставить его с ChickenSandwich EntityTypeConfiguration следующим образом:
Property(x => x.CheeseColor.Value).HasColumnName("CheeseColor");
Если я оставлю это до ColorMapping и не создаю явного отображения на ChickenSandwichMapping, он просто не помещает его в базу данных. Если я сопоставляю ему путь x.CheeseColor.Value, я получаю страшное:
System.InvalidOperationException: настроенное свойство "CheeseColor" не объявленное свойство на объекте 'Куриный сендвич'. Убедитесь, что не были явно исключены из модели и что это действительный примитив свойство..
Edit
Мне не удалось получить общую версию обертки 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");