Veg*_*gar 5 .net c# serialization mongodb mongodb-.net-driver
我的数据库中有一个集合,用于记录事件。每种类型的事件都有一组不同的数据。我已经用以下类定义了它:
[CollectionName("LogEvent")]
public class LogEvent
{
public LogEvent(string eventType)
{
EventType = eventType;
EventData = new Dictionary<string, object>();
}
public string EventType { get; private set; }
[BsonExtraElements]
public IDictionary<string, object> EventData { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
现在 - 这在某种程度上非常有效。只要EventData字典的元素是简单类型...
var event = new LogEvent("JobQueues"){
EventData = new Dictionary<string, object>(){
{ "JobId": "job-123" },
{ "QueueName": "FastLane" }
}
}
_mongoCollection.InsertOne(event);
Run Code Online (Sandbox Code Playgroud)
...我得到 mongo 文件,如
{
_id: ObjectId(...),
EventType: "JobQueued",
JobId: "job-123",
QueueName: "FastLane"
}
Run Code Online (Sandbox Code Playgroud)
但是一旦我尝试将自定义类型添加到字典中,事情就会停止工作。
var event = new LogEvent("JobQueues"){
EventData = new Dictionary<string, object>(){
{ "JobId": "job-123" },
{ "QueueName": "FastLane" },
{ "JobParams" : new[]{"param-1", "param-2"}},
{ "User" : new User(){ Name = "username", Age = 10} }
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我这样的错误 ".NET type ... cannot be mapped to BsonType."
如果我删除[BsonExtraElements]标签,[BsonDictionaryOptions(DictionaryRepresentation.Document)]它会开始序列化没有错误的东西,但它会给我一个我不喜欢的完全不同的文档..
{
_id: ObjectId(...),
EventType: "JobQueued",
EventData: {
JobId: "job-123",
QueueName: "FastLane",
User: {
_t: "User",
Name: "username",
Age: 10
},
JobParams : {
_t: "System.String[]",
_v: ["param-1", "param-2"]
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想要的是以下结果:
{
_id: ObjectId(...),
EventType: "JobQueued",
JobId: "job-123",
QueueName: "FastLane",
User: {
Name: "username",
Age: 10
},
JobParams : ["param-1", "param-2"]
}
Run Code Online (Sandbox Code Playgroud)
有谁知道如何实现这一目标?
(我使用的是 C# mongodriver v2.3)
MongoDriver 也是如此,因为它需要类型信息才能将其反序列化回来。您可以做的是为 User 类编写并注册您自己的 CustomMapper:
public class CustomUserMapper : ICustomBsonTypeMapper
{
public bool TryMapToBsonValue(object value, out BsonValue bsonValue)
{
bsonValue = ((User)value).ToBsonDocument();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
启动程序时的某处:
BsonTypeMapper.RegisterCustomTypeMapper(typeof(User), new CustomUserMapper());
Run Code Online (Sandbox Code Playgroud)
这会起作用,并且我已经成功地按照您的要求精确地序列化了您的数据。
但是: 当您想将其反序列化回来时,您将获得您的User类Dictionary,因为驱动程序将没有有关 hiow 的信息来反序列化它: