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

C# MongoDB Driver调用Aggregate()始终抛出类型转换异常

问题根因

这个报错和Lookup管道操作没有任何关系,核心原因是C#实体类定义与MongoDB集合中实际存储的字段类型不匹配:实体中声明为bool类型的属性,在数据库中实际存储为"true"/"false"格式的字符串,MongoDB C#驱动反序列化BSON文档时,尝试将BsonString强转为BsonBoolean,就会抛出你看到的InvalidCastException。
不追加任何Lookup阶段、直接调用Aggregate().ToListAsync()依然报错,就是因为反序列化动作在管道执行完成、结果映射到实体类的环节触发,和具体管道阶段无关。调试时看到单个对象大量属性抛出异常,是调试器访问属性时触发了未处理的反序列化错误,并非所有字段都存在问题。
调试异常截图


排查方法

直接查询原始BSON文档定位不匹配的字段,不要先映射到自定义实体类:

// 取1条原始BSON文档查看实际存储结构
var rawDocs = await Items
    .Aggregate()
    .Limit(1)
    .ToListAsync<BsonDocument>();

将返回的原始文档和Item实体类的属性定义逐一对比,找到所有实体中声明为bool、但数据库中实际存储为字符串类型的字段即可。


修复方案

二选一即可:

  • 方案1:修正存量数据(推荐)
    批量将集合中存储为字符串的布尔值转换为MongoDB原生布尔类型,在Mongo Shell执行以下命令:

    // 将集合名、字段名替换为实际业务使用的名称
    db.你的集合名.updateMany(
      { 你的布尔字段名: { $type: "string" } },
      [
        { $set: { 你的布尔字段名: { $eq: [ "$你的布尔字段名", "true" ] } } }
      ]
    )
    

    执行完成后字段类型和C#实体定义完全对齐,原有业务代码不需要任何修改即可正常运行。

  • 方案2:自定义序列化器兼容(适合不方便修改存量数据的场景)
    给类型不匹配的布尔属性添加自定义序列化特性,让驱动自动兼容字符串、布尔两种存储格式:

    using MongoDB.Bson.Serialization;
    using MongoDB.Bson.Serialization.Attributes;
    
    public class Item
    {
        // 其余属性保持原有定义不变
        [BsonSerializer(typeof(BsonStringToBoolSerializer))]
        public bool 目标布尔属性 { get; set; }
    }
    
    public class BsonStringToBoolSerializer : IBsonSerializer<bool>
    {
        public Type ValueType => typeof(bool);
    
        public bool Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var reader = context.Reader;
            return reader.CurrentBsonType switch
            {
                BsonType.Boolean => reader.ReadBoolean(),
                BsonType.String => bool.TryParse(reader.ReadString(), out var res) && res,
                _ => { reader.SkipValue(); return false; }
            };
        }
    
        public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, bool value)
        {
            context.Writer.WriteBoolean(value);
        }
    
        public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
        {
            if (value is bool boolVal) Serialize(context, args, boolVal);
            else context.Writer.WriteNull();
        }
    
        object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            return Deserialize(context, args);
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:27:42