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.
- +1 je suis intéressé par les opinions quant à savoir si ce genre de chose doit être appliquée avec des tables séparées et un FK contrainte ou juste une simple contrainte si quelqu'un a des idées?
- Pas de planification sur le répondeur car cela aura tendance à être très subjectif, mais pour OLTP/ODS je voudrais utiliser des tableaux séparés avec un FK contrainte. Pour un DSS solution de production de rapports, je les éliminer et de les stocker de l'enum nom symbolique (ou description) dans le tableau de rapport avec les autres faits.
Vous devez vous connecter pour publier un commentaire.
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:
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:
À la fin 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)
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.
(EnumType, EnumId)
(dont la valeur par défaut index cluster serait de commencer avecEnumType
)? Il semble tout à fait arbitraire, contraire au moment de votre deuxième, troisième, quatrième, etc... enum ID ne commence pas à 1, et si vous ajoutez plus de valeurs de l'enum, il aura des lacunes dans les Identifiants. Par exemple, si vous définissez un type enum 2 pour la "qualité" avec les valeurs initiales de "mauvais"=6, "pauvre"=7, "ok"=8, "bon"=9, "grand"=10 alors enum type 3 de "statut" avec "on"=11, "off"=12, alors vous voulez ajouter "très bien" à votre "qualité" de type plus tard, il va avoir des id 13.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!
De la Table DB:
C# Extrait:
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.
Quels 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 cela et 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.Si vous avez besoin de stocker en DB de la chaîne de valeurs de l'enum champ, vaut mieux le faire comme montrer ci-dessous.
Par exemple, il peut être nécessaire si vous utilisez SQLite, qui ne supportent pas les champs de type enum.
Je ne suis pas sûr si c'est la plus flexible, mais vous pourriez tout simplement stocker la chaîne de versions. Il est certes lisible, mais peut-être difficile à maintenir. Les Enums convertir à partir de chaînes et de retour assez facilement:
Pourquoi ne pas essayer de séparer les enums tout à fait de la DB? J'ai trouvé cet article pour être une grande référence, tout en travaillant sur quelque chose de semblable:
http://stevesmithblog.com/blog/reducing-sql-lookup-tables-and-function-properties-in-nhibernate/
Les idées de la elle devrait s'appliquer indépendamment de ce que la DB que vous utilisez. Par exemple, dans MySQL, vous pouvez utiliser le bouton "enum" type de données pour assurer la conformité avec votre codé les énumérations:
http://dev.mysql.com/doc/refman/5.0/en/enum.html
Acclamations
Un DB première approche peut être utilisée par la création d'un tableau cohérent pour chaque enum où la colonne Id, le nom correspond à nom de la table. Il est avantageux d'avoir les valeurs de l'enum disponibles dans la base de données à l'appui des contraintes de clés étrangères et de l'amicale des colonnes dans les vues. Nous sommes actuellement en soutenant ~100 types enum dispersés dans de nombreuses bases de données versionnées.
Pour un Code-Première de préférence, le T4 stratégie présentée ci-dessous pourrait probablement être inversé pour écrire dans la base de données.
Chaque table peut être importé en C# à l'aide d'un T4 modèle (*.tt) script.
les contenus sont toujours la même ligne: <#@ include
fichier="..\EnumGenerator.ttinclude" #>
"Exécuter l'Outil Personnalisé" (nous n'avons pas de mise à jour automatique encore). Il va ajouter/mettre à jour un .cs fichier au projet:
Et, enfin, le peu gnarly T4 script (simplifié de nombreuses solutions de contournement). Il devra être adaptée à votre environnement. Un indicateur de débogage peut générer des messages dans le C#. Il y a aussi un "Debug T4 Modèle" option lors d'un clic droit sur l' .tt fichier.
EnumGenerator.ttinclude:
Espérons-le, entity framework, un jour, le soutien d'une combinaison de ces réponses pour offrir le C# enum taper fort dans les dossiers et de la base de données mise en miroir de valeurs.
Vous n'avez pas besoin de faire quelque chose si vous voulez stocker des entiers. Juste une carte de votre propriété dans les EF.
Si vous souhaitez stocker des chaînes de caractères utiliser le convertisseur.
Int (db type est de type smallint):
Chaîne (db est de type varchar(50)):
Si vous voulez sauvegarder votre base de données de l'utilisation des données d'utilisation smallint comme une colonne en db. Mais les données ne seront pas lisibles par l'homme et vous devez définir un index sur chaque enum élément et de ne jamais toucher:
Si vous souhaitez apporter des données en db plus lisible, vous pouvez les enregistrer comme des chaînes de caractères (par exemple de type varchar(50)). Vous n'avez pas à vous soucier des indices et vous avez juste besoin de mise à jour des chaînes en db lorsque vous modifiez les noms enum. Inconvénients: la taille de la colonne obtient des données d'utilisation plus cher. Cela signifie que si vous avez une table dans un délai de 1 000 000 de lignes qu'il pourrait avoir un impact sur la db de la taille et de la performance.
Également comme une solution, vous pouvez utiliser des noms enum:
Ou utiliser votre propre convertisseur de noms en db plus courte:
Plus d'informations peuvent être trouvées ici:
EF: https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/data-types/enums
EFCore: https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions