Le stockage des Enums en tant que chaînes de caractères dans MongoDB
Est-il un moyen pour stocker des Enums en tant que chaîne de caractères des noms plutôt que des valeurs ordinales?
Exemple:
Imaginer que j'ai un enum:
public enum Gender
{
Female,
Male
}
Maintenant si certains imaginaire Utilisateur existe avec
...
Gender gender = Gender.Male;
...
il sera stocké dans la base de données MongoDb comme { ...le "Genre" : 1 ... }
mais je préfère quelque chose comme ceci { ...le "Genre" : "Mâle" ... }
Est-ce possible? Un mappage personnalisé, de réflexion, de trucs, quoi.
Mon contexte: je l'utilise fortement typé collections de plus de POCO (eh bien, je marque ARs et utiliser le polymorphisme de temps en temps). J'ai un mince d'accès aux données de la couche d'abstraction dans une forme d'Unité De Travail. Donc je ne suis pas la sérialisation/désérialisation de chaque objet, mais je peux (et dois) définir certains ClassMaps. J'utilise officielle MongoDb pilote + fluide-mongodb.
- Je voudrais l'éviter. La chaîne de valeur prend beaucoup plus d'espace qu'un entier. Je voudrais cependant, si la persistance est impliqué donner des valeurs déterministes pour chaque article dans votre enum afin Féminin = 1, Mâle = 2 donc, si l'enum est ajouté à plus tard ou de l'ordre des éléments de changé que vous ne finissent pas avec des problèmes.
- Oui, je pensais à l'espace mais il n'est pas un problème puisque je n'ai que peu de cas où je préfère honnête Enums. Et vous avez vu juste, les changements futurs est ce qui me dérange. Je suppose que le marquage de toutes les valeurs de l'enum est une solution viable, en effet. Merci Chris!
Vous devez vous connecter pour publier un commentaire.
MongoDB .Conducteur NET permet d'appliquer des conventions afin de déterminer comment certaines correspondances entre les types CLR et les éléments de base de données sont traitées.
Si vous voulez que cela s'applique à tous vos énumérations, vous n'avez qu'à configurer les conventions une fois par domaine d'application (généralement lors du démarrage de votre application), par opposition à l'ajout d'attributs à tous vos types ou manuellement carte de chaque type:
Vous pouvez personnaliser la carte pour la classe qui contient la enum et de préciser que le membre peut être représenté par une chaîne de caractères. Cela permettra de gérer à la fois la sérialisation et la désérialisation de l'enum.
Je suis toujours à la recherche d'un moyen de spécifier que les énumérations être globalement représentés comme des chaînes de caractères, mais c'est la méthode que j'utilise actuellement.
Utilisation MemberSerializationOptionsConvention de définir une convention sur la façon dont un enum sera sauvé.
Avec chauffeur 2.x je l'ai résolu en utilisant une spécifique sérialiseur:
J'ai trouvé que l'application de Ricardo Rodriguez réponse n'est pas suffisante dans certains cas correctement sérialiser les valeurs de l'enum à la chaîne dans MongoDb:
Si votre structure de données implique des valeurs enum être enfermé dans une boîte en objets, MongoDb la sérialisation de ne pas utiliser l'ensemble
EnumRepresentationConvention
à sérialiser.En effet, si vous regardez à la mise en œuvre de MongoDb du conducteur ObjectSerializer, il permettra de résoudre la
TypeCode
de la boîte de valeur (Int32
pour les valeurs de l'enum), et l'utilisation de ce type pour stocker votre valeur d'enum dans la base de données. Donc en boîte les valeurs de l'enum être sérialisé en tant queint
valeurs. Ils resteront commeint
des valeurs lors de l'être désérialisé ainsi.Pour changer cela, il est possible d'écrire une coutume
ObjectSerializer
qui mettra en œuvre l'ensembleEnumRepresentationConvention
si la boîte de valeur est un enum. Quelque chose comme ceci:et puis définissez la coutume sérialiseur à utiliser pour la sérialisation des objets:
Faire cela permettra d'assurer boîte enum valeurs seront stockées sous forme de chaînes de caractères comme le "unboxed" ceux.
Gardez cependant à l'esprit que lors de la désérialisation de votre document, la boîte de la valeur restera une chaîne de caractères. Il ne sera pas converti en arrière à l'original de la valeur d'enum. Si vous avez besoin de convertir la chaîne en arrière à l'original de la valeur d'enum, une discrimination devra probablement être ajouté dans votre document afin que le sérialiseur peut savoir quel est le type enum pour desrialize dans.
Une façon de le faire serait de stocker un bfils document au lieu de simplement une chaîne de caractères, dans laquelle, en matière de discrimination (
_t
) et un champ de valeur (_v
) serait utilisé pour stocker le type enum et de sa chaîne de valeur.J'ai fini par l'affectation de valeurs enum éléments, comme suggéré par Chris Smith dans un commentaire:
Pas exactement ce que je cherchais, mais il semble que il n'y a aucune autre manière autour.
Les réponses postées ici fonctionnent bien pour
TEnum
etTEnum[]
, cependant, ne fonctionnent pas avecDictionary<TEnum, object>
. Vous pouvez obtenir ce lors de l'initialisation du processus à l'aide de code, mais je voulais le faire par des attributs. J'ai créé un flexibleDictionarySerializer
qui peut être configuré avec un sérialiseur pour la clé et la valeur.L'utilisation de ce genre, où à la fois la clé et la valeur sont des types enum, mais pourrait être n'importe quelle combinaison de sérialiseurs: