Могу ли я хранить перечисления в виде строк в EF 5?
Мы используем EF CF некоторое время в нашем решении. Большие поклонники! До этого момента мы использовали хак для поддержки перечислений (создание дополнительного поля в модели, игнорирование отображения enum durring и сопоставление дополнительного поля с столбцом в db, который мы бы использовали). Традиционно мы сохраняем наши перечисления как строки (varchars) в БД (делает его приятным и читаемым). Теперь с поддержкой перечисления в EF 5 (бета-версия 2) похоже, что он поддерживает только преобразования перечислений в столбцы int в БД.... Можем ли мы получить EF 5 для хранения наших перечислений в качестве их строкового представления.
Где "Тип" - это перечисление типа DocumentType
public enum DocumentType
{
POInvoice,
NonPOInvoice,
Any
}
Я попытался отобразить его, используя:
public class WorkflowMap : EntityTypeConfiguration<Model.Workflow.Workflow>
{
public WorkflowMap()
{
ToTable("Workflow", "Workflow");
...
Property(wf => wf.Type).HasColumnType("varchar");
}
}
Я думал, что это будет волшебная пуля, но..
Это просто бросает:
Указанная схема недействительна. Ошибки: (571,12): ошибка 2019: участник Указанное отображение недействительно. Тип 'Dodson.Data.DataAccess.EFRepositories.DocumentType [Nullable = False, DefaultValue =]' члена "Тип" в типе "Dodson.Data.DataAccess.EFRepositories.Workflow" несовместим с 'SqlServer.varchar [Nullable = False, DefaultValue =, MaxLength = 8000, Unicode = False, FixedLength = False] члена "Тип" в типе "CodeFirstDatabaseSchema.Workflow".
Ваши мысли?
Ответы
Ответ 1
В настоящее время это невозможно. Enum в EF имеет те же ограничения, что и перечисления в CLR - они просто называются множеством целочисленных значений. Проверьте эту статью для подтверждения:
Определения типа enum EF живут в концептуальном слое. Аналогично CLR перечисляет EF перечисления имеют базовый тип, который является одним из Edm.SByte, Edm.Byte, Edm.Int16, Edm.Int32 или Edm.Int64 с Edm.Int32, являющимся default type, если ни один не указан.
Я разместил статью и связанное предложение об этой проблеме, Если вы хотите увидеть эту функцию в будущем, проголосуйте за предложение.
Ответ 2
Я ударил эту проблему несколько недель назад. Лучшее, что я мог придумать, немного взломан.
У меня есть перечисление Gender для класса Person, и я использую аннотации данных для сопоставления строки с базой данных и игнорирования перечисления.
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Column("Gender")]
public string GenderString
{
get { return Gender.ToString(); }
private set { Gender = value.ParseEnum<Gender>(); }
}
[NotMapped]
public Gender Gender { get; set; }
}
И метод расширения, чтобы получить правильное перечисление из строки.
public static class StringExtensions
{
public static T ParseEnum<T>(this string value)
{
return (T)Enum.Parse(typeof(T), value, true);
}
}
Подробнее см. это сообщение - http://nodogmablog.bryanhogan.net/2014/11/saving-enums-as-strings-with-entity-framework/