69 votes

La meilleure méthode pour stocker Enum dans la Base de données

Quelle est la meilleure méthode de stockage d'une Enum dans une Base de données à l'aide de C# Et Visual Studio et de Données MySQL Connector.

Je vais créer un nouveau projet avec plus de 100 Enums, et la majorité d'entre eux devront être stockées dans la base de données. La création de convertisseurs pour chacun pourrait être un processus de longue haleine donc je me demandais si visual studio ou quelqu'un a des méthodes pour cela que je n'ai pas entendu off.

67voto

Joao Leme Points 2217
    [Required]
    public virtual int PhoneTypeId
    {
        get
        {
            return (int)this.PhoneType;
        }
        set
        {
            PhoneType = (PhoneTypes)value;
        }
    }
    [EnumDataType(typeof(PhoneTypes))]
    public PhoneTypes PhoneType { get; set; }

public enum PhoneTypes
{
    Mobile = 0,
    Home = 1,
    Work = 2,
    Fax = 3,
    Other = 4
}

Fonctionne comme un charme! Pas besoin de convertir (int)Enum ou (Enum)int dans le code. Utilisez simplement l'enum et ef le premier code permettra d'économiser de l'int pour vous. p.s.: "[EnumDataType(typeof(PhoneTypes))]" attribut n'est pas nécessaire, juste un supplément si vous voulez des fonctionnalités supplémentaires.

Sinon, vous pouvez faire:

[Required]
    public virtual int PhoneTypeId { get; set; }
    [EnumDataType(typeof(PhoneTypes))]
    public PhoneTypes PhoneType
    {
        get
        {
            return (PhoneTypes)this.PhoneTypeId;
        }
        set
        {
            this.PhoneTypeId = (int)value;
        }
    }

11voto

Muad'Dib Points 14260

Nous stockons les nôtres en tant que ints ou longs et alors nous pouvons simplement cast 'em avant en arrière. Probablement pas le plus solide de la solution, mais que ce que nous faisons.

nous utilisons typés, de sorte que, par exemple:

eunum BlockTreatmentType 
{
    All = 0
};

// blockTreatmentType is an int property
blockRow.blockTreatmentType = (int)BlockTreatmentType.All;
BlockTreatmentType btt = (BlockTreatmentType)blockRow.blocktreatmenttype;

3voto

Paul Sasik Points 37766

En fin de compte, vous aurez besoin d'une excellente façon de traiter avec la répétition des tâches de codage tels que les enum convertisseurs. Vous pouvez utiliser un générateur de code comme MyGeneration ou CodeSmith parmi beaucoup d'autres, ou peut-être un ORM mapper comme nHibernate qui se charge de tout pour vous.

Comme pour la structure... avec des centaines d'énumérations, je voudrais d'abord envisager d'essayer d'organiser les données dans une table unique qui pourrait ressembler à quelque chose comme ceci: (pseudo-sql)

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

qui vous permettra de stocker vos enum infos dans une table unique. EnumType pourrait également être une clé étrangère d'une table qui définit les différentes énumérations.

Votre biz objets seraient liés à cette table via EnumId. Le type enum est-il que pour l'organisation et le filtrage dans l'INTERFACE utilisateur. En utilisant tout cela dépend bien sûr de votre structure du code et du domaine du problème.

Btw, dans ce scénario, vous devez définir un index cluster sur EnumType plutôt que de laisser la valeur par défaut de cluster idx qui est créé sur le PKey.

3voto

João Angelo Points 24422

Certaines choses que vous devriez prendre en considération.

Est l'énumération colonne va être directement utilisés par d'autres applications, comme par exemple les rapports. Cela permettra de limiter la possibilité de l'énumération d'être stockée dans son format de nombre entier parce que la valeur n'ont pas de signification lorsqu'ils sont présents dans un rapport, à moins que les rapports ont une logique personnalisée.

Quelles sont les i18n besoin pour votre application? Si il prend en charge uniquement une langue, vous pouvez économiser de l'énumération comme du texte et créer une méthode d'aide à convertir à partir d'une chaîne de description. Vous pouvez utiliser [DescriptionAttribute] pour les ce et les méthodes pour la conversion peut probablement être trouvés par la recherche de la SORTE.

Si d'autre part vous avez besoin de langue de multiple de soutien et de l'application externe d'accès à vos données, vous pouvez commencer à envisager si l'énumération sont vraiment la réponse. Autre option, comme les tables de consultation peuvent être considérés, si le scénario est plus complexe.

Les énumérations sont excellents quand ils sont autonomes dans le code... quand ils traversent la frontière, les choses ont tendance à être un peu sale.


Mise à jour:

Vous pouvez convertir un entier en utilisant Enum.ToObject méthode. Cela implique que vous connaissez le type de l'énumération lors de la conversion. Si vous souhaitez vous rendre complètement générique, vous devez stocker le type de l'énumération à côté de la valeur dans la base de données. Vous pouvez créer dictionnaire des données de tables de soutien pour vous dire que les colonnes qui sont les énumérations et de quel type sont eux.

3voto

cortijon Points 823

Si vous voulez un magasin de tous vos énumérations des valeurs, vous pouvez essayer les dessous de tables pour stocker les énumérations et de leurs membres, et l'extrait de code pour ajouter ces valeurs. J'aimerais le faire uniquement au moment de l'installation, cependant, étant donné que ces valeurs ne changera jamais jusqu'à ce que vous recompilez!

Table DB:

   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# Extrait:

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);
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X