Storing names as strings in MongoDB

Is there a way to save Enums as string names rather than ordinal values?

Example:

Imagine I have this listing:

public enum Gender { Female, Male } 

Now, if some imaginary user exists with

 ... Gender gender = Gender.Male; ... 

it will be stored in the MongoDb database as {... "Gender": 1 ...}

but I would prefer something like this {... "Paul": "Man" ...}

Is it possible? Custom mapping, reflection tricks, whatever.

My context: I use strongly typed collections over POCO (well, I mark AR and sometimes use polymorphism). I have a subtle level of data access abstraction in the Unit Of Work form. Therefore, I do not serialize / deserialize each object, but I can (and do) define some ClassMaps. I am using the official MongoDb + flu-mongodb driver.

+42
c # mongodb mongodb-.net-driver
Aug 09 2018-11-12T00:
source share
6 answers

The MongoDB.NET driver allows you to apply conventions to determine how certain mappings between CLR types and database elements are handled.

If you want this to apply to all your enumerations, you only need to configure the conventions once in the AppDomain (usually when the application starts), and not add attributes to all your types or manually map each type:

 // Set up MongoDB conventions var pack = new ConventionPack { new EnumRepresentationConvention(BsonType.String) }; ConventionRegistry.Register("EnumStringConvention", pack, t => true); 
+26
Sep 18 '13 at 14:09
source share
 using MongoDB.Bson; using Newtonsoft.Json; using Newtonsoft.Json.Converters; public class Person { [JsonConverter(typeof(StringEnumConverter))] // JSON.Net [BsonRepresentation(BsonType.String)] // Mongo public Gender Gender { get; set; } } 
+73
Jul 17 2018-12-17T00:
source share

You can set up a class map for the class containing the enumeration and specify that the element will be represented by a string. This will handle both serialization and deserialization of the enumeration.

 if (!MongoDB.Bson.Serialization.BsonClassMap.IsClassMapRegistered(typeof(Person))) { MongoDB.Bson.Serialization.BsonClassMap.RegisterClassMap<Person>(cm => { cm.AutoMap(); cm.GetMemberMap(c => c.Gender).SetRepresentation(BsonType.String); }); } 

I'm still looking for a way to indicate that enums will be globally represented as strings, but this is the method I'm currently using.

+13
Feb 02 '12 at 19:50
source share

Use MemberSerializationOptionsConvention to define an agreement on how the enumeration will be saved.

 new MemberSerializationOptionsConvention(typeof(Gender), new RepresentationSerializationOptions(BsonType.String)) 
+5
Jul 23 '13 at 11:16
source share

In the end, I assigned values ​​to the elements of the enumeration, as suggested by Chris Smith in the comment:

I would avoid this. A string value takes up more space than an integer. However, I would like, while maintaining persistence, to give deterministic values ​​to each element in your enumeration, therefore Female = 1 , Male = 2 , therefore, if the enumeration is added later or the order of the elements changes, as a result of which you will not encounter problems.

Not quite what I was looking for, but there seems to be no other way.

+1
Aug 25 2018-11-14T00:
source share

With the 2.x driver, I decided using a specific serializer :

 BsonClassMap.RegisterClassMap<Person>(cm => { cm.AutoMap(); cm.MapMember(c => c.Gender).SetSerializer(new EnumSerializer<Gender>(BsonType.String)); }); 
+1
Aug 19 '17 at 23:19 on
source share



All Articles