Как отобразить перечисление как строку в базе данных - PullRequest
7 голосов
/ 09 января 2011

Мой стол:

create table MyTable (
    Id int identity(1,1) not null,
    MyStatus char(2) not null
)
insert into MyTable(MyStatus) select 'A'

Класс и перечисление:

public class MyTable
{
    public virtual int Id { get; set; }
    public virtual MyTableStatus MyStatus { get; set; }
}

public enum MyTableStatus
{
    A,
    B
}

Отображение:

public MyTableMap()
{
    Id(x => x.Id);
    Map(x => x.MyStatus);
}

Когда я выполняю следующий тест, я получаю System.FormatException: входная строка была в неправильном формате ...

[Test]
public void Blah()
{
    MyTable myTable = Session.Get<MyTable>(1);
    Assert.That(myTable.MyStatus, Is.EqualTo(MyTableStatus.A));
}

Как правильно сопоставить перечисление с его строковым представлением в базе данных?

Редактировать - я пишу свое приложение в существующей базе данных, которую я не могу легко изменить, потому что оно также используется другими приложениями. Поэтому некоторые поля в базе данных (которые я хотел бы представить как перечисления в моем приложении) имеют тип int, а некоторые - тип char (2).

Ответы [ 2 ]

5 голосов
/ 09 января 2011

Вам нужно создать собственный IUserType для преобразования enum в его строковое представление и обратно.Здесь есть хороший пример на C # и пример в VB.NET для работы с перечислениями здесь (прокрутите вниз до реализации IUserType).

0 голосов
/ 09 января 2011

Ну, насколько мне известно, NHibernate хранит перечисления как строки только в БД по умолчанию. Я думаю, я знаю, в чем здесь проблема. То, как вы создаете таблицу, неверно.

если вы используете Nhibernate, используйте функцию построения конфигурации для создания таблиц вместо того, чтобы создавать таблицы вручную, и тогда вы увидите, что ваше перечисление хранится в виде строки.

Мы широко используем перечисления в нашем приложении, и для нас имеет смысл хранить их как строки в БД. Причины просты, если я добавлю новое значение в перечисление, то, если значения по умолчанию не установлены, тогда мой код и мои данные тесно связаны, чего я определенно не хотел бы.

SimpleConfig.ExposeConfiguration(c => new SchemaExport(c).Create(false, true)).BuildConfiguration();

Также вместо char можно использовать varchar для свойства.

После обновления: Не могли бы вы, ребята, сделать какую-то манипуляцию перед тем, как сохранить ее в базе данных? Таким образом, если вы хотите сохранить новые списки символов, напишите функцию, которая генерирует для вас значение типа int, и сохраните ее в правильной форме, а затем сохраните ее или, если вы хотите упростить ее, функция может иметь регистр переключения.

Итак, что вы делаете, у вас нет доступа к этому свойству, которое извлекается из БД, вместо этого вы добавляете новое свойство в класс Status, которое в основном имеет логику получения соответствующего перечисления.

Как вы думаете, это хорошая идея?

Надеюсь, это поможет.

...