По умолчанию Entity Framework Code-First маппит enum свойства к sql колонкам типа integer. Мапинг в обе стороны проходит без проблем, и вообще всё работает отлично. Однако, может возникнуть необходимость изменить тип sql колонки на nvarchar. Стандартными средствами Code-First подход настраивать типы колонок не позволяет. Тем не менее можно провернуть следующие ухищрения.
Пусть у нас есть тип AuditRecord, который маппится в БД. В нём находится поле ActionType типа AuditActionType (enum). Таким образом, получаем следующее:
Здесь я использовал extension-метод ParseEnum, который выглядит следующим образом:
Сеттер свойства ActionTypeString сделан приватным, чтобы предотвратить присвоения произвольных строк извне.
Основные минусы такого подхода:
Последнюю проблему можно решить изоляцией логики фильтрации на уровне репозиториев, чтобы знания об особенностях реализации не расползались за уровень DAL.
Пусть у нас есть тип AuditRecord, который маппится в БД. В нём находится поле ActionType типа AuditActionType (enum). Таким образом, получаем следующее:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class AuditRecord { [Required] [Column("ActionType")] [MaxLength(32)] public string ActionTypeString { get { return ActionType.ToString(); } private set { ActionType = EnumExtensions.ParseEnum<AuditActionType>(value); } } [NotMapped] public AuditActionType ActionType { get; set; } } |
Здесь я использовал extension-метод ParseEnum, который выглядит следующим образом:
1 2 3 4 5 6 7 | public class EnumExtensions { public static T ParseEnum<T>(String text) { return (T)Enum.Parse(typeof(T), text, true); } } |
Основные минусы такого подхода:
- Работа со строковыми полями на больших объёмах данных в общем случае в БД медленнее, чем с integer.
- При фильтрации сущностей по данному полю для получения эффективного запроса в БД необходимо писать подобную лапшу:
context.AuditRecords.Where(ar => ar.ActionTypeString == AuditActionType.SomeAction.ToString());
Комментариев нет:
Отправить комментарий