Подтвердить что ты не робот

Могу ли я хранить перечисления в виде строк в 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".

Ваши мысли?

4b9b3361

Ответ 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/