C# MongoDb 序列化 Dictionary<string, object>

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)

Mak*_*kin 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)

这会起作用,并且我已经成功地按照您的要求精确地序列化了您的数据。

但是: 当您想将其反序列化回来时,您将获得您的UserDictionary,因为驱动程序将没有有关 hiow 的信息来反序列化它:

在此输入图像描述