C#调用MongoDB BulkWriteAsync抛出System.InvalidCastException问题排查
问题
我们在尝试将对象保存至MongoDB时,会偶发无规律的System.InvalidCastException错误,错误信息为:
无法将类型为'MongoDB.Bson.BsonObjectId'的对象转换为类型'MongoDB.Bson.BsonBoolean'。
经排查,代码中并未主动尝试将ObjectId转换为布尔值,更新逻辑代码如下:
foreach (var update in updates) { update.UpdateVersionNumber(); var updateFilterDef = Builders<AmazonOrder>.Filter; var updateFilter = updateFilterDef.Eq(o => o.Id, update.Id) & (updateFilterDef.Eq(o => o.Version, update.LoadedVersion) | updateFilterDef.Exists(o => o.Version, false)); list.Add(new ReplaceOneModel<AmazonOrder>(updateFilter, update)); }
随后调用批量写入方法:
var result = await _context.Orders.BulkWriteAsync(list, cancellationToken: cancellationToken);
获取到的堆栈跟踪信息为:
bool AsBooleanGetter(object) Called from: JsonPropertyInfoOfT.cs in bool JsonPropertyInfo<T>.GetMemberAndWriteJson(object obj, ref WriteStack state, Utf8JsonWriter writer)
错误成因分析
- 序列化时的数据类型不匹配:堆栈跟踪指向System.Text.Json的序列化逻辑,说明在将
AmazonOrder对象序列化为MongoDB可识别格式时,某个布尔类型属性对应的数据库字段实际存储的是ObjectId类型。这种情况通常是历史数据遗留(比如早期代码bug、手动修改文档)导致,当驱动尝试读取该字段并转换为布尔值时触发异常。 - 并发修改引发的数据篡改:偶发无规律的特性指向并发场景。多个请求或线程同时操作同一条
AmazonOrder数据时,可能出现竞态条件,导致布尔字段被意外写入ObjectId值,后续序列化读取时就会抛出类型转换错误。 - 实体类映射配置错误:检查
AmazonOrder类的Bson映射配置,是否存在布尔属性被错误映射到ObjectId字段的情况(比如误加[BsonId]特性到布尔属性);或者属性类型从ObjectId改为布尔后,未同步清理或迁移数据库中的旧数据,导致新旧数据类型不兼容。 - 批量操作中的对象状态异常:如果
updates列表中的AmazonOrder对象存在共享引用,在循环执行UpdateVersionNumber()时,并发修改可能导致对象属性被意外篡改,出现布尔属性被赋值为ObjectId的情况,最终在序列化时触发异常。
内容的提问来源于stack exchange,提问作者DanSharpe
相关产品推荐
相关产品推荐

