每当使用自定义序列化程序时,它都会在数据库中正确设置属性值,但对象上的属性仍然是默认值。
自定义序列化程序:
public class RngSerializer : SerializerBase<int>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, int value)
{
var rng = new Random().Next(0, 100);
Console.WriteLine($"Generated rng {rng}");
context.Writer.WriteInt32(rng);
}
}
对象:
public class Entity
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonSerializer(typeof(RngSerializer))]
public int RngProp { get; set; }
}
执行插入的代码:
var entity = new Entity();
collection.InsertOne(entity);
Console.WriteLine($"Inserted Id {entity.Id}, Rng {entity.RngProp}");
您可以看到序列化程序称为更正,当我检查数据库中的对象时,也会设置该值。但是,驱动程序似乎没有正确设置属性。
生成 rng 32
插入 ID 5e4ade582c509931f4467e38, rng 0
我通过在插入发生之前触发序列化程序找到了解决方案;
var bson = entity.ToBson();
var hydrated = BsonSerializer.Deserialize<Entity>(bson);
collection.InsertOne(hydrated);
hydrated.Id = entity.Id;
并相应地更改序列化程序;
public class RngSerializer : SerializerBase<int>
{
#region Overrides of SerializerBase<int>
public override int Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
return context.Reader.ReadInt32();
}
#endregion
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, int value)
{
//This part is important otherwise it will call the rng twice, once when the ToBson() is called and once when inserting.
if (value == 0)
{
var rng = new Random().Next(0, 100);
Console.WriteLine($"Generated rng {rng}");
context.Writer.WriteInt32(rng);
}
else
{
context.Writer.WriteInt32(value);
}
}
}
这可能不是双重序列化最优雅的方式,但它给了我预期的结果。
更新:将值传递给封装在引用类型中的序列化程序。
public class MyInt
{
public int RngProp { get; set; }
}
public class Entity
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonSerializer(typeof(RngSerializer))]
public MyInt MyProp { get; set; } = new MyInt();
}
public class RngSerializer : SerializerBase<MyInt>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, MyInt value)
{
var rnd = new Random().Next(0, 100);
value.RngProp = rnd;
Console.WriteLine($"written rng {rnd}");
context.Writer.WriteInt32(rnd);
}
public override MyInt Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
return new MyInt
{
RngProp = context.Reader.ReadInt32()
};
}
}
var entity = new Entity();
collection.InsertOne(entity);
Console.WriteLine($"Inserted Id {entity.Id}, Rng {entity.MyProp.RngProp}");
var result = collection.FindSync(e => e.Id == entity.Id).Single();
Console.WriteLine($"Retrieved Id {entity.Id}, Rng {result.MyProp.RngProp}");
Console.ReadLine();