C# .NET中MongoDB查询嵌套Documents数组返回为空问题
问题原因
返回空集合的核心原因是多态类型反序列化规则缺失:
- 你MongoDB中存储的Documents数组子项带有
_t字段,这是MongoDB C#驱动默认用来识别多态子类型的判别字段,值为对应派生类的标识(你库里存的是Cpf、RG)。 - 但你的C#代码中没有为Documents的基类注册对应的派生类型映射规则,驱动无法识别
_t对应的具体类型,反序列化时会直接跳过无法识别类型的子文档,最终返回空集合。 - 这个问题和你写的查询逻辑无关,属于序列化配置层的问题,所以不管是按Id查还是查全量,都会出现数组为空的情况。
修复方案
不需要修改你现有仓储层的查询代码,只需要在程序启动初始化Mongo连接时,补充多态类型映射配置即可。
- 首先确认你的C#实体类结构和存储结构匹配,参考结构如下:
// Documents子项的基类 public class DocumentBase { public string type { get; set; } public string number { get; set; } } // 对应_t: "Cpf"的派生类 public class Cpf : DocumentBase { } // 对应_t: "RG"的派生类 public class RG : DocumentBase { } // 根实体类 public class Person { public Guid Id { get; set; } public DateTimeOffset createdDate { get; set; } public bool active { get; set; } public string PersonType { get; set; } public string CompanyName { get; set; } public string TradingName { get; set; } // 注意属性名要和库中字段名一致,为Documents public List<DocumentBase> Documents { get; set; } }
- 在Mongo初始化逻辑中注册多态映射规则:
using MongoDB.Bson.Serialization; // 程序启动时执行一次即可 BsonClassMap.RegisterClassMap<DocumentBase>(cm => { cm.AutoMap(); // 标记该类为多态序列化的根类 cm.SetIsRootClass(true); // 注册所有派生类型,第二个参数为库中_t字段存储的对应值 cm.AddKnownType(typeof(Cpf), "Cpf"); cm.AddKnownType(typeof(RG), "RG"); });
如果你不需要做派生类的差异化处理,只是想把Documents子项统一按基类解析,不需要区分Cpf/RG类型,可以直接在基类上加
[BsonIgnoreExtraElements]特性,驱动就会忽略_t字段,直接按基类属性反序列化:[BsonIgnoreExtraElements] public class DocumentBase { public string type { get; set; } public string number { get; set; } }
配置完成后重新调用查询接口,Documents数组就可以正常反序列化返回内容了。
内容的提问来源于stack exchange,提问作者Marcos Cruz
相关产品推荐
相关产品推荐

