Каков лучший метод хранения Перечисления в Базе данных с помощью C# И Visual Studio и MySQL Data Connector.
Я собираюсь быть созданием нового проекта с более чем 100 Перечислениями, и большинство их должно будет быть сохранено в базе данных. Создание преобразователей для каждого было бы долгим обветренным процессом поэтому, я задаюсь вопросом, есть ли у Visual Studio или кого-то какие-либо методы для этого, что я не услышал прочь.
Некоторые вещи следует учитывать.
Будет ли столбец перечисления использоваться напрямую другими приложениями, например, в отчетах. Это ограничит возможность сохранения перечисления в целочисленном формате, потому что это значение не будет иметь смысла, если оно присутствует в отчете, если отчеты не имеют настраиваемой логики.
В чем нуждается i18n для вашего приложения? Если он поддерживает только один язык, вы можете сохранить перечисление как текст и создать вспомогательный метод для преобразования из строки описания. Вы можете использовать [DescriptionAttribute]
для этого, и методы преобразования, вероятно, можно найти, выполнив поиск SO.
Если, с другой стороны, вам необходимо поддерживать многоязычный и внешний доступ приложений к вашим данным, вы можете подумать, действительно ли перечисление является ответом. Другой вариант, например таблицы поиска, может быть рассмотрен, если сценарий более сложен.
Перечисления превосходны, когда они самодостаточны в коде ... когда они пересекают эту границу, все становится немного запутанным.
Обновление:
Вы можете преобразовать из целого числа, используя метод Enum.ToObject
. Это означает, что вы знаете тип перечисления при преобразовании. Если вы хотите сделать его полностью универсальным, вам необходимо сохранить тип перечисления вместе со значением в базе данных. Вы можете создать вспомогательные таблицы словаря данных, чтобы сообщить вам, какие столбцы являются перечислениями и какого они типа.
Мы храним наши как целые или длинные, а затем можем просто перебрасывать их туда и обратно. Возможно, не самое надежное решение, но это то, что мы делаем.
мы используем типизированные наборы данных, например:
enum BlockTreatmentType
{
All = 0
};
// blockTreatmentType is an int property
blockRow.blockTreatmentType = (int)BlockTreatmentType.All;
BlockTreatmentType btt = (BlockTreatmentType)blockRow.blocktreatmenttype;
Я не уверен, что он самый гибкий, но вы можете просто сохранить их строковые версии. Это, конечно, читается, но, возможно, трудно поддерживать. Перечисления довольно легко конвертировать из строк и обратно:
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 );
}
Если вам нужен магазин всех ваших значений перечислений, вы можете попробовать следующие таблицы для хранения перечислений и их членов, а также фрагмент кода для добавления этих значений. Однако я бы сделал это только во время установки, поскольку эти значения никогда не изменятся, пока вы не перекомпилируете!
Таблица БД:
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);
}
}
В конце концов, вам понадобится отличный способ справиться с повторяющимися задачами кодирования, такими как преобразователи перечислений. Вы можете использовать генератор кода, такой как MyGeneration или CodeSmith среди многих других, или, возможно, ORM-преобразователь, такой как nHibernate , чтобы сделать все за вас.
Что касается структуры ... с сотнями перечислений, я бы сначала подумал о том, чтобы попытаться организовать данные в единую таблицу, которая может выглядеть примерно так: (pseudo sql)
MyEnumTable(
EnumType as int,
EnumId as int PK,
EnumValue as int )
, которая позволит вам хранить информацию о вашем перечислении в единой таблице. EnumType также может быть внешним ключом к таблице, которая определяет различные перечисления.
Ваши бизнес-объекты будут связаны с этой таблицей через EnumId. Тип перечисления используется только для организации и фильтрации в пользовательском интерфейсе. Использование всего этого, конечно, зависит от структуры вашего кода и предметной области.
Между прочим, в этом сценарии вам нужно установить кластерный индекс для EnumType, а не оставлять идентификатор кластера по умолчанию, созданный на PKey.