Лучший метод для хранения Перечисления в Базе данных

Каков лучший метод хранения Перечисления в Базе данных с помощью C# И Visual Studio и MySQL Data Connector.

Я собираюсь быть созданием нового проекта с более чем 100 Перечислениями, и большинство их должно будет быть сохранено в базе данных. Создание преобразователей для каждого было бы долгим обветренным процессом поэтому, я задаюсь вопросом, есть ли у Visual Studio или кого-то какие-либо методы для этого, что я не услышал прочь.

58
задан Michal Ciechan 15 April 2010 в 15:08
поделиться

5 ответов

Некоторые вещи следует учитывать.

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

В чем нуждается i18n для вашего приложения? Если он поддерживает только один язык, вы можете сохранить перечисление как текст и создать вспомогательный метод для преобразования из строки описания. Вы можете использовать [DescriptionAttribute] для этого, и методы преобразования, вероятно, можно найти, выполнив поиск SO.

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

Перечисления превосходны, когда они самодостаточны в коде ... когда они пересекают эту границу, все становится немного запутанным.


Обновление:

Вы можете преобразовать из целого числа, используя метод Enum.ToObject . Это означает, что вы знаете тип перечисления при преобразовании. Если вы хотите сделать его полностью универсальным, вам необходимо сохранить тип перечисления вместе со значением в базе данных. Вы можете создать вспомогательные таблицы словаря данных, чтобы сообщить вам, какие столбцы являются перечислениями и какого они типа.

3
ответ дан 24 November 2019 в 19:03
поделиться

Мы храним наши как целые или длинные, а затем можем просто перебрасывать их туда и обратно. Возможно, не самое надежное решение, но это то, что мы делаем.

мы используем типизированные наборы данных, например:

enum BlockTreatmentType 
{
    All = 0
};

// blockTreatmentType is an int property
blockRow.blockTreatmentType = (int)BlockTreatmentType.All;
BlockTreatmentType btt = (BlockTreatmentType)blockRow.blocktreatmenttype;
10
ответ дан 24 November 2019 в 19:03
поделиться

Я не уверен, что он самый гибкий, но вы можете просто сохранить их строковые версии. Это, конечно, читается, но, возможно, трудно поддерживать. Перечисления довольно легко конвертировать из строк и обратно:

public enum TestEnum
{
    MyFirstEnum,
    MySecondEnum
}

static void TestEnums()
{
    string str = TestEnum.MyFirstEnum.ToString();
    Console.WriteLine( "Enum = {0}", str );
    TestEnum e = (TestEnum)Enum.Parse( typeof( TestEnum ), "MySecondEnum", true );
    Console.WriteLine( "Enum = {0}", e );
}
1
ответ дан 24 November 2019 в 19:03
поделиться

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

Таблица БД:

   create table EnumStore (
    EnumKey int NOT NULL identity primary key,
    EnumName varchar(100)
);
GO

create table EnumMember (
    EnumMemberKey int NOT NULL identity primary key,
    EnumKey int NOT NULL,
    EnumMemberValue int,
    EnumMemberName varchar(100)
);
GO
--add code to create foreign key between tables, and index on EnumName, EnumMemberValue, and EnumMemberName

Фрагмент C #:

void StoreEnum<T>() where T: Enum
    {
        Type enumToStore = typeof(T);
        string enumName = enumToStore.Name;

        int enumKey = DataAccessLayer.CreateEnum(enumName);
        foreach (int enumMemberValue in Enum.GetValues(enumToStore))
        {
            string enumMemberName = Enum.GetName(enumToStore, enumMemberValue);
            DataAccessLayer.AddEnumMember(enumKey, enumMemberValue, enumMemberName);
        }
    }
3
ответ дан 24 November 2019 в 19:03
поделиться

В конце концов, вам понадобится отличный способ справиться с повторяющимися задачами кодирования, такими как преобразователи перечислений. Вы можете использовать генератор кода, такой как MyGeneration или CodeSmith среди многих других, или, возможно, ORM-преобразователь, такой как nHibernate , чтобы сделать все за вас.

Что касается структуры ... с сотнями перечислений, я бы сначала подумал о том, чтобы попытаться организовать данные в единую таблицу, которая может выглядеть примерно так: (pseudo sql)

MyEnumTable(
EnumType as int,
EnumId as int PK,
EnumValue as int )

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

Ваши бизнес-объекты будут связаны с этой таблицей через EnumId. Тип перечисления используется только для организации и фильтрации в пользовательском интерфейсе. Использование всего этого, конечно, зависит от структуры вашего кода и предметной области.

Между прочим, в этом сценарии вам нужно установить кластерный индекс для EnumType, а не оставлять идентификатор кластера по умолчанию, созданный на PKey.

3
ответ дан 24 November 2019 в 19:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: