解决:无法将MongoDB.Bson.BsonNull转换为BsonDocument异常
问题场景
代码示例
模型类
// 模型类 public class User { public string FirstName {get; set;} public Address? Address{get; set;} // 当Address为null时出现问题 } public class Address { public string Street { get; set; } public string City { get; set; } public string State { get; set; } }
DB上下文类
// DB上下文类 public class MongoDBContext : DbContext { public DbSet<User> User { get; init; } public static EPCMongoDBContext Create(IMongoDatabase database) => new(new DbContextOptionsBuilder<EPCMongoDBContext>() .UseMongoDB(database.Client, database.DatabaseNamespace.DatabaseName) .Options); public EPCMongoDBContext(DbContextOptions options) : base(options) {} protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<User>().ToCollection("user"); } }
检索用户代码
// 检索用户代码 var item = _context.User.FirstOrDefault(x => x.FirstName == "Scott");
问题说明
当Address字段为null时,检索User对象会抛出类型转换异常,尝试使用[BsonIgnoreIfNull]特性无效。
错误信息:
在MongoDB.EntityFrameworkCore.dll中发生类型为'System.InvalidCastException'的异常,未在用户代码中处理:“无法将MongoDB.Bson.BsonNull类型的对象转换为MongoDB.Bson.BsonDocument类型。”
解决方案
1. 显式配置属性转换规则
在OnModelCreating中为Address属性添加自定义转换逻辑,直接处理BsonNull到null的映射:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<User>() .ToCollection("user") .Property(u => u.Address) .HasConversion( v => v, v => v is BsonNull ? null : BsonSerializer.Deserialize<Address>(v.AsBsonDocument) ); }
2. 使用OwnsOne标记嵌套实体
针对MongoDB EF Core,用OwnsOne明确声明Address是User的可选嵌套实体,框架会自动处理null场景:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<User>() .OwnsOne(u => u.Address, b => { b.Property(a => a.Street); b.Property(a => a.City); b.Property(a => a.State); }) .ToCollection("user"); }
3. 修正序列化配置
结合BsonClassMap配置null忽略规则,确保序列化和反序列化时正确识别null值:
// 在User类中添加静态构造函数 static User() { BsonClassMap.RegisterClassMap<User>(cm => { cm.AutoMap(); cm.MapProperty(u => u.Address).SetIgnoreIfNull(true); }); }
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

