You need to enable JavaScript to run this app. C#使用MongoDB驱动执行Aggregate Lookup查询触发类型转换异常
优惠活动
大模型
产品
解决方案
定价
更多

C#使用MongoDB驱动执行Aggregate Lookup查询触发类型转换异常

MongoDB聚合关联查询接口报类型转换异常排查

复现场景

基于MongoDB C#驱动开发双集合关联查询接口时,编写的聚合查询代码如下:

var res = _postCollection.Aggregate()
    .Lookup("_commentCollection", "Comments", "_id", "result")
    .ToList();
return OK(res);

通过Postman调用该接口时,抛出如下类型转换异常:

System.InvalidCastException: Unable to cast object of type 'MongoDB.Bson.BsonObjectId' to type 'MongoDB.Bson.BsonBoolean'.
   at get_AsBoolean(Object )
   at System.Text.Json.JsonPropertyInfoNotNullable`4.OnWrite(WriteStackFrame& current, Utf8JsonWriter writer)
...............

报错核心原因

  • 调用Aggregate()方法时未指定泛型输出类型,驱动默认以无类型的BsonDocument形式承载查询结果
  • ASP.NET Core内置的System.Text.Json序列化器会遍历BsonDocument的所有公开属性,错误将BsonValue基类上的IsBoolean/IsObjectId等元数据标识属性识别为需要序列化的业务字段;当序列化器访问IsBoolean属性时,内部会直接读取Bson值的AsBoolean属性做类型转换,若当前Bson值为BsonObjectId类型,就会触发类型转换失败
  • 原Lookup查询的参数映射逻辑本身不存在顺序错误,但由于没有绑定明确的输出结构,查询返回的字段无法匹配业务模型,也无法实现预期的接口返回效果

可落地的修正方案

  • 为聚合查询绑定明确的强类型输出DTO,从根源上避免无类型BsonDocument的序列化问题。修正后的代码示例:
    // 定义与查询输出结构匹配的DTO
    public class PostWithCommentsDto
    {
        public ObjectId Id { get; set; }
        public string Title { get; set; }
        // 按需补充其他Post模型需要返回的属性
        public List<Comment> Comments { get; set; }
    }
    
    // 调整聚合查询逻辑,指定强类型输出
    var res = _postCollection.Aggregate<Post, PostWithCommentsDto>()
        .Lookup(
            foreignCollectionName: "_commentCollection",
            localField: post => post.Comments,
            foreignField: comment => comment.Id,
            result: dto => dto.Comments
        )
        .ToList();
    return OK(res);
    
  • 如果必须保留无类型查询逻辑,可在项目的System.Text.Json配置中添加专门的BsonValue序列化转换器,适配Bson类型的序列化规则,避免默认序列化器错误读取Bson内部的元数据属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 07:24:04