Нет, вы не можете сделать это напрямую: когда вы сопоставляете свой класс с свойством Enum
, это свойство сопоставляется с базой данных int
, и вы не можете изменить это каким-либо образом. Я имею в виду, что, как вы не можете изменить модель, нет никакого способа, чтобы перехватить и преобразовать значение Enum
свойства в строку, так как модель упорно хочет int
.
Тем не менее, есть несколько способов, чтобы сделать его работу:
- , имеющие свойство строки для ключа и
[NotMapped]
Enum
свойство, которое обновляет этот ключ. СМ. ЗАМЕЧАНИЕ. Но ключ должен быть общедоступным и, таким образом, доступен через код приложения.
- , используя класс, есть только свойство перечислимого и используются в домене приложения, а другой класс, который используется для вашей модели EF, и отображать значения, например, с помощью
ValueInjecter
или Automapper
Обычно я беру первый путь и использую атрибут, который позволяет мне определить строковый ключ для каждого значения Enum
, поэтому вы можете повторно использовать этот шаблон во всех случаях, когда это необходимо.
Примечание: эта часть ответа не так: вы можете отображать любое имущественное regardles модификатора (public
, protected
, private
, internal
...). Соглашения EF включают только свойства public
, и нет никаких аннотаций данных, которые могут преодолеть это ограничение. Но вы можете использовать его с Fluent API. Однако, поскольку свойство является приватным, вы не можете получить к нему доступ напрямую, используя Fluent API. Есть несколько решений, чтобы сделать это описано здесь: Code First Data Annotations on non-public properties
Если вы будете следовать этому пути, вы можете иметь класс, как это:
public class MyEntity
{
// ...
[NotMapped]
public EnumType Value
{
get { /* return KeyForEnum converted to EnumType value */ }
set { /* set KeyForEnum value from the received EnumType value*/}
}
// Use some mechanism to map this private property
private string KeyForEnum { get; set; }
// ...
}
Как вы можете видеть, если вы используете класс, как это, в приложении объект будет иметь свойство EnumType
, но в базе данных это будет строка.
Одна из уловок, чтобы иметь возможность сопоставить его с помощью Fluent API заключается в следующем:
1) Добавить статическое свойство, которое возвращает выражение, способное выбрать свойство из объекта этого класса, т.е.
public static readonly Expression<Func<MyEntity,string>> KeyForEnumExpression
= me => me.KeyForEnum;
2) Используйте его в беглом API, чтобы получить свойство отображается, например, так:
modelBuilder
.Entity()
.Property(MyEntity.KeyForEnumExpression)
ПОСЛЕДНЕГО ПРИМЕЧАНИЕ: Это будет изменить класс POCO путем добавления статического свойства только для чтения. Вы можете использовать Reflection вместо этого, чтобы создать выражение для доступа к частной собственности, как вы можете здесь: EF 4.1 Code First, ¿map private members?. Это на испанском, но вы можете посмотреть прямо на код
Я бы сказал, что это не проблема, которую стоит решить. Суррогатные ключи превосходят как производительность, так и ремонтопригодность. Знаете ли вы, что в 1960-х годах сократились государственные сокращения? Кроме того, что, если добавить дополнительные города? – TheCatWhisperer
Я думаю, что это много читаемо, чтобы иметь имена в базе данных, чем некоторые случайные числа, зависящие от версии моего кода. – mFeinstein
Чтобы узнать читаемость в БД: 1. Виды 2. Вот почему у вас есть таблица поиска Что касается кода, вот почему вы используете перечисление в первую очередь. И, к сожалению, если вы используете EF, приложение уже напрямую связано с вашей БД. – TheCatWhisperer