MongoDB .NET驱动在创建三层嵌套文档时失败

编程语言 2026-07-10

我一直无法使用.NET MongoDB驱动程序将MongoDB文档嵌套到第三层。顶层类有一个第二级对象的列表。第二级类有一个第三级对象的列表。然而,插入操作未能包含第三级文档的数据。该项目是一个使用 MongDB.Driver v3.7 的控制台应用程序。

我也尝试手动注册第三级文档的定义,但那段代码可能有误。不过,驱动是否需要注册所有位于第二级之下的文档,以便驱动能够“检测”到它?

文档的类定义:

public class LibraryUser
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
    public required int UserId { get; set; }
    public List<Book> Books { get; set; } = [];
    public void AddBook(Book book)
    {
        Books.Add(book);
    }
}
public class Book
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
    public string BookTitle { get; set; }
    public int Price { get; set; }
    List<Review> Reviewers { get; set; } = [];
    public void addReview(Review review)
    {
        Reviewers.Add(review);
    }
}
public class Review
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
    public string Reviewer { get; set; }
    public int Grade { get; set; }
}

用于创建嵌套文档的代码:

iMongoDatabase.CreateCollection("LibraryUsers");
LibraryUsersCollection = iMongoDatabase!.GetCollection<LibraryUser>("LibraryUsers");
LibraryUser userDoc = new()  // First Level 
{
    UserId = 999999
};
Book book = new()  // Second Level 
{
    BookTitle = "Old Yeller",
    Price = 11
};
Review review = new() // Third Level 
{
    Reviewer = "Corin",
    Grade = 55
};
book.addReview(review); // Add Review doc to Book 
userDoc.AddBook(book);  // Add Book doc to LibraryUser doc
LibraryUsersCollection.InsertOne(userDoc);

为注册 Review 类的代码——但没有帮助。

MongoDB.Bson.Serialization.BsonClassMap.RegisterClassMap<Review>(classmap =>
{
    classmap.AutoMap();
    classmap.MapMember(p => p.Reviewer);
    classmap.MapMember(p => p.Grade);
});

通过Mongosh查看的结果数据:

db.LibraryUsers.find()
[
  {
    _id: ObjectId('69e22dcac06b765666fcda19'),
    UserId: 999999,
    Books: [
      {
        _id: ObjectId('69e22dcac06b765666fcda1a'),
        BookTitle: 'Old Yeller',
        Price: 11
      }
    ]
  }
]

GitHub仓库

解决方案

该属性必须是 public,以便能够进行(反)序列化。

public class Book
{
    ...

    public List<Review> Reviewers { get; set; } = [];

    ...
}

此外,移除对 Review 类的已注册类映射:

MongoDB.Bson.Serialization.BsonClassMap.RegisterClassMap<Review>(...)

因为不需要。


Bonus: 如果你想在序列化中包含私有属性,可以通过以下方式之一

public class Book
{
    ...

    [BsonElement("Reviewers")]
    List<Review> Reviewers { get; set; } = [];

    ...
}

或为 Book 注册类映射。

BsonClassMap.RegisterClassMap<Book>(cm => 
{
    cm.AutoMap();
    cm.MapProperty(nameof(Book.Review));
});
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章