【问题标题】:How to define a default discriminator for a polymorphic class mapping in C# MongoDB如何在 C# MongoDB 中为多态类映射定义默认鉴别器
【发布时间】:2021-06-03 13:07:33
【问题描述】:
我已将一些遗留数据重构为具有多态结构:
class Shape {}
class Rectangle : Shape {}
class MyClass
{
public Shape shape;
}
BsonClassMap.RegisterClassMap<Shape>(cm =>
{
cm.AutoMap();
cm.SetIsRootClass(true);
cm.AddKnownType(typeof(Rectangle));
});
这对新数据非常有效,鉴别器 _t 是为形状和矩形创建的。我遇到的问题是遗留数据都是矩形类型,但在数据库中没有鉴别器 _t ,因为它创建时不存在多态性。当我尝试读取其中一个对象时,我收到反序列化错误,因为它无法将旧版 Rectangle 映射到 Shape。我宁愿不必运行数据迁移来添加鉴别器,如果缺少鉴别器,有没有办法让我将反序列化类型默认为 Rectangle?
【问题讨论】:
标签:
c#
mongodb
mongodb-.net-driver
【解决方案1】:
我想通了,解决方案是实现一个自定义序列化器来处理反序列化,像这样:
public class ShapeNullDiscriminatorSerializer : SerializerBase<Shape>
{
public override Shape Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
if (context.Reader.CurrentBsonType == BsonType.Null)
{
context.Reader.ReadNull();
return default(Shape);
}
var bsonDoc = BsonSerializer.Deserialize<BsonDocument>(context.Reader);
if (!bsonDoc.Contains("_t"))
return BsonSerializer.Deserialize<Rectangle>(bsonDoc);
return BsonSerializer.Deserialize<Shape>(bsonDoc);
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, FeedbackConfig value)
{
BsonSerializer.Serialize<Shape>(context.Writer, value, null, args);
}
}
然后像这样映射到父类上:
BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
cm.AutoMap();
cm.MapMember(mc => mc.shape).SetSerializer(new ShapeNullDiscriminatorSerializer());
});