【问题标题】: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());
    });
    

    【讨论】:

      猜你喜欢
      • 2021-05-05
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 1970-01-01
      • 2020-06-23
      相关资源
      最近更新 更多