You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB C#:泛型注册类映射正常,直接用类型注册失效

问题:MongoDB C#驱动非泛型注册类映射仅序列化接口成员

我有一组对象,每个对象都包含EventData属性,该属性对应多种继承自IEventData接口的类型,示例文档结构如下:

{ _id: '...', EventData: { _t: 'TypeA', ... } }
{ _id: '...', EventData: { _t: 'TypeB', ... } }

使用泛型版本注册类映射时,EventData能正确序列化所有属性和类型鉴别器:

BsonClassMap.RegisterClassMap<TypeA>();
// 写入集合的完整数据
// { _id: '...', EventData: { _t: 'TypeA', InterfaceProperty: '...', ClassProperty: '...' } }

但因为事件类型数量多,我尝试用反射自动化注册:遍历所有实现IEventData的类型,使用非泛型方式注册类映射,结果仅序列化了接口成员:

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(i => i.GetTypes())
    .Where(t => typeof(IEventData).IsAssignableFrom(t));

foreach (var type in types)
{
    // 跳过接口
    if (type.IsInterface)
        continue;
        
    if (!BsonClassMap.IsClassMapRegistered(type))
        BsonClassMap.RegisterClassMap(new BsonClassMap(type));
 }

// 仅接口属性被写入
// { _id: '...', EventData: { _t: 'TypeA', InterfaceProperty: '...' } }

请问非泛型方式注册类映射时,需要设置什么才能让完整的类型数据存入集合?


解决方案

直接实例化BsonClassMap时,默认只会映射接口成员,不会自动处理类自身的属性。需要手动调用AutoMap()方法,让驱动扫描并映射类型的所有公共成员(包括类自身定义的属性)。

修改反射注册代码如下:

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(i => i.GetTypes())
    .Where(t => typeof(IEventData).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);

foreach (var type in types)
{
    if (!BsonClassMap.IsClassMapRegistered(type))
    {
        var classMap = new BsonClassMap(type);
        // 自动映射当前类型的所有公共成员(接口+类自身属性)
        classMap.AutoMap();
        // 显式设置类型鉴别器,和泛型注册的默认行为对齐
        classMap.SetDiscriminator(type.Name);
        BsonClassMap.RegisterClassMap(classMap);
    }
}

关键说明:

  • AutoMap()是核心:它会递归扫描类型的所有公共属性、字段,包括继承自接口的成员和类自身定义的成员。
  • 过滤抽象类:添加!t.IsAbstract避免注册无法实例化的抽象类型。
  • 显式设置鉴别器:SetDiscriminator(type.Name)确保类型鉴别器和泛型注册的默认逻辑一致,保证反序列化时能正确识别类型。

修改后,非泛型注册的类映射就能像泛型版本一样,将完整的类型数据序列化到MongoDB集合中。

内容的提问来源于stack exchange,提问作者Juzzbott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:24:28