F# MongoDB自定义序列化程序实现

F# MongoDB自定义序列化程序实现,f#,mongodb-.net-driver,F#,Mongodb .net Driver,我是MongoDB新手,正在尝试让C#驱动程序序列化F#类。我使用可变F#fields&一个无参数构造函数来处理automapper类,但实际上我需要保持不变性,所以我开始考虑实现一个IBsonSerializer来执行自定义序列化。我还没有找到任何关于编写其中一个的文档,所以我只是试图从驱动程序源代码中推断 我遇到了一个问题,在序列化程序上调用反序列化方法时,CurrentBsonType被设置为EndOfDocument,而不是我所期望的开始。我用C语言写了一个等价物,只是为了确保它不是某种

我是MongoDB新手,正在尝试让C#驱动程序序列化F#类。我使用可变F#fields&一个无参数构造函数来处理automapper类,但实际上我需要保持不变性,所以我开始考虑实现一个IBsonSerializer来执行自定义序列化。我还没有找到任何关于编写其中一个的文档,所以我只是试图从驱动程序源代码中推断

我遇到了一个问题,在序列化程序上调用反序列化方法时,CurrentBsonType被设置为EndOfDocument,而不是我所期望的开始。我用C语言写了一个等价物,只是为了确保它不是某种奇怪的东西,但问题依然存在。序列化部分似乎工作正常,可以从shell中查询。以下是示例代码:

课程日历{
公共字符串Id{get;private set;}
public DateTime[]假日{get;private set;}
公共日历(字符串id,日期时间[]假日){
Id=Id;
假日=假日;
}
}
类CalendarSerializer:BsonBaseSerializer{
public override void Serialize(BsonWriter BsonWriter,类型nominalType,对象值,IBsonSerializationOptions){
var日历=(日历)值;
bsonWriter.WriteStartDocument();
bsonWriter.WriteString(“\u id”,calendar.id);
bsonWriter.WriteName(“假日”);
var ser=new ArraySerializer();
serial.Serialize(bsonWriter,typeof(DateTime[]),calendar.Holidays,null);
bsonWriter.WriteEndDocument();
}
公共重写对象反序列化(BsonReader BsonReader,类型nominalType,类型actualType,IBSOnSSerializationOptions选项){
if(nominalType!=typeof(日历)| | actualType!=typeof(日历))
抛出新的BsonSerializationException();
if(bsonReader.CurrentBsonType!=BsonType.Document)
抛出新的FileFormatException();
bsonReader.ReadStartDocument();
var id=bsonReader.ReadString(“_id”);
var ser=new ArraySerializer();
var holidays=(DateTime[])序列反序列化(bsonReader,typeof(DateTime[]),null);
bsonReader.ReadEndDocument();
返回新日历(id,假日);
}
public override bool GetDocumentId(对象文档、输出对象id、输出类型idNominalType、输出IIdGenerator idGenerator){
var日历=(日历)文档;
id=calendar.id;
idNominalType=类型(字符串);
idGenerator=新StringObjectiveGenerator();
返回true;
}
公共覆盖无效SetDocumentId(对象文档,对象id){
抛出新的NotImplementedException(“SetDocumentId未实现”);
}
}

当CurrentBsonType不是Document时,反序列化中会出现FileFormatException。我使用的是最新版本的驱动程序源代码1.4。

我最终解决了这个问题。我应该使用bsonReader.GetCurrentBsonType()而不是bsonReader.CurrentBsonType。这将从缓冲区中读取BsonType,而不仅仅是查看缓冲区中的最后一个内容。我还修复了一个后续的bug去序列化。更新后的方法如下所示:

public override对象反序列化(BsonReader BsonReader,类型nominalType,类型actualType,IBsonSerializationOptions){
if(nominalType!=typeof(日历)| | actualType!=typeof(日历))
抛出新的BsonSerializationException();
if(bsonReader.GetCurrentBsonType()!=BsonType.Document)
抛出新的FileFormatException();
bsonReader.ReadStartDocument();
var id=bsonReader.ReadString(“_id”);
bsonReader.ReadName();
var ser=new ArraySerializer();
var holidays=(DateTime[])序列反序列化(bsonReader,typeof(DateTime[]),null);
bsonReader.ReadEndDocument();
返回新日历(id,假日);
}