我有一些[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
的模型。
当我尝试使用C#驱动程序插入mongoDB时,会出现异常,并显示以下消息:
使用DictionaryRepresentation.Document时,键值必须序列化为字符串。
当然,我可以添加属性public MyEnum {
A,
B
}
[BsonDictionaryOptions(DictionaryRepresentation.Document)]
public Dictionary<MyEnum, object> MyData { get; set; }
并且它可以工作,但我希望能够将枚举作为字符串保存。
{
"MyData": {
"B": "xxxx",
"A": "xxxx"
}
}
我想在mongo中出现类似的东西,原因不同。
[BsonRepresentation(BsonType.String)]
对于单个枚举,我只能使用#balloon-circle {
width: 150px;
height: 150px;
background: rgb(255,100,100);
-moz-border-radius: 150px;
-webkit-border-radius: 150px;
border-radius: 150px;
top:5px;
}
属性,但是如何告诉驱动程序字典将枚举密钥序列化为字符串?
答案 0 :(得分:4)
问题是字典序列化程序不强制键是字符串类型。 为了解决这个问题,请创建一个自己的序列化程序,并使用BsonSerializer属性选择它。
public class EnumDictionarySerializer<TKey, TDictionary> : DictionarySerializerBase<TDictionary>
where TKey : struct
where TDictionary : class, IDictionary, new()
{
public EnumDictionarySerializer():base(DictionaryRepresentation.Document, new EnumSerializer<TKey>(BsonType.String), new ObjectSerializer())
{
}
protected override TDictionary CreateInstance()
{
return new TDictionary();
}
}
答案 1 :(得分:1)
这个答案对于评论来说太长了,但它引用了评论。
这需要反射来在程序运行时更改此对象的类型。起初这是一个非常糟糕的主意,第二,这将是非常缓慢的。
我建议您为此目的使用字典实现或使用扩展类:
public MyEnum {
A,
B
}
[BsonDictionaryOptions(DictionaryRepresentation.Document)]
public MyDictionary<String, MyEnum, object> MyData {get;set;}
public class MyDictionary<T1,T2,T3> : IDictionary{
Dictionary<T1, T3> Dict = new Dictionary<T1, T3>();
//implement dictionary...
}
public static class ExtentionsDictionary<T1,T2>{
public static T2 Get(this IDictionary dict, MyEnum enum){
var key = enum.ToString();
return dict[key];
}
//Rest of the implementation
}
答案 2 :(得分:1)
基于@ Hugh.walsh的答案,我创建了一个灵活的DictionarySerializer
,可以为该键和值配置一个序列化器。
public class DictionarySerializer<TDictionary, KeySerializer, ValueSerializer> : DictionarySerializerBase<TDictionary>
where TDictionary : class, IDictionary, new()
where KeySerializer : IBsonSerializer, new()
where ValueSerializer : IBsonSerializer, new()
{
public DictionarySerializer() : base(DictionaryRepresentation.Document, new KeySerializer(), new ValueSerializer())
{
}
protected override TDictionary CreateInstance()
{
return new TDictionary();
}
}
public class EnumStringSerializer<TEnum> : EnumSerializer<TEnum>
where TEnum : struct
{
public EnumStringSerializer() : base(BsonType.String) { }
}
这样的用法,其中键和值都是枚举类型,但是可以是任何类型:
[BsonSerializer(typeof(DictionarySerializer<
Dictionary<FeatureToggleTypeEnum, LicenseFeatureStateEnum>,
EnumStringSerializer<FeatureToggleTypeEnum>,
EnumStringSerializer<LicenseFeatureStateEnum>>))]
public Dictionary<FeatureToggleTypeEnum, LicenseFeatureStateEnum> FeatureSettings { get; set; }