代码之家  ›  专栏  ›  技术社区  ›  RoadieRich

MongoDB:无法创建<type>的实例,因为它是一个抽象类

  •  2
  • RoadieRich  · 技术社区  · 5 月前

    我有以下课程:

    public abstract class Test { }
    
    public class ConcreteTest1: Test
    {
        public string Foo {get; set; }
        //...
    }
    
    public class ConcreteTest2: Test
    {
        public int AnInt { get; set; }
        //...
    }
    
    public class TestScript
    {
        public ObjectId _id { get; set; } = new();
        public string PartNumber { get; set; }
        public IList<Test> Tests { get; set; } = [];
    }
    

    我可以储存一个 TestScript 在MongoDB中很好,但当我尝试检索它时,我会得到

    系统。FormatException:“反序列化类TestScript的Tests属性时出错:无法创建Test的实例,因为它是一个抽象类。”

    我的MongoDB文档看起来像这样:

    {
      "_id": {
        "$oid": "6780467598922ae42e13a832"
      },
      "PartNumber": "1234-12345-12",
      "Tests": [
        {  
          "_t": "ConcreteTest1",
          "Foo": "bar",
          ...
        },
        {
          "_t": "ConcreteTest2",
          "AnInt": 42
          ...
        }
      ]
    }
    

    我的检索代码看起来像

    var collection = db.GetCollection<TestScript>("TestScripts");
    
    var testScript = await collection.Find(ts => ts.PartNumber == partNumber).SingleOrDefaultAsync(cancellationToken);
    return testScript?.Tests ?? [];
    

    我如何让反序列化器识别子类的类型?它将类型名插入为 _t ,所以一定有办法使用它,对吧?

    这是我第一次尝试使用MongoDB,所以如果我在其他方面做错了,请告诉我。

    1 回复  |  直到 5 月前
        1
  •  2
  •   Guru Stron    5 月前

    尝试指定 BsonKnownTypesAttribute :

    [BsonKnownTypes(typeof(ConcreteTest1), typeof(ConcreteTest2))]
    public abstract class Test { }
    

    或者,如果使用属性不是一个选项,您可以使用 BsonClassMap.RegisterClassMap<T>() 手动创建类图(针对层次结构中的每个类):

    BsonClassMap.RegisterClassMap<Test>();
    BsonClassMap.RegisterClassMap<ConcreteTest1>();
    BsonClassMap.RegisterClassMap<ConcreteTest2>();
    

    请参阅: