在MongoDB中将枚举存储为string
有没有办法将枚举存储为string名称而不是序号值?
例:
想象一下,我有这个枚举:
public enum Gender { Female, Male }
现在,如果一些虚构的用户存在
... Gender gender = Gender.Male; ...
它将被存储在MongoDb数据库中:{…“Gender”:1 …}
但我更喜欢这样的{…“Gender”:“Male”…}
这可能吗? 自定义映射,reflection技巧,不pipe。
我的上下文:我使用POCO强types集合(好吧,我标记AR和偶尔使用多态)。 我有一个工作单元forms的瘦数据访问抽象层。 所以我不序列化/反序列化每个对象,但我可以(和确实)定义一些ClassMaps。 我使用官方的MongoDb驱动程序+stream利的mongodb。
MongoDB .NET驱动程序允许您应用约定来确定如何处理CLRtypes和数据库元素之间的特定映射。
如果您希望将其应用于所有枚举,则只需为每个AppDomain设置约定(通常在启动应用程序时),而不是为所有types添加属性或手动映射每个types:
// Set up MongoDB conventions var pack = new ConventionPack { new EnumRepresentationConvention(BsonType.String) }; ConventionRegistry.Register("EnumStringConvention", pack, t => true);
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; } }
您可以为包含枚举的类自定义类映射,并指定该成员由string表示。 这将处理枚举的序列化和反序列化。
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); }); }
我仍然在寻找一种方法来指定枚举被全局表示为string,但这是我目前使用的方法。
使用MemberSerializationOptionsConvention定义关于如何保存枚举的约定。
new MemberSerializationOptionsConvention(typeof(Gender), new RepresentationSerializationOptions(BsonType.String))
我最终为枚举项赋值,正如克里斯·史密斯(Chris Smith)在评论中所build议的那样:
我会避免它。 string值占用比整数更多的空间。 但是,如果涉及到持久性的话,给你枚举中的每个项目赋予确定性的值,所以
Female = 1
,Male = 2
所以如果后来增加了枚举,或者项目的顺序改变了,那么你不会遇到问题。
不完全是我正在寻找,但似乎没有其他办法。
使用驱动程序2.x我解决了使用特定的序列化程序 :
BsonClassMap.RegisterClassMap<Person>(cm => { cm.AutoMap(); cm.MapMember(c => c.Gender).SetSerializer(new EnumSerializer<Gender>(BsonType.String)); });