反序列化期间的'意外元素:XX'MongoDB C#

smo*_*sen 5 persist mongodb c#-4.0 mongodb-.net-driver

我正在尝试使用以下代码将对象持久化到MongoDB中:

public class myClass
{
    public string Heading { get; set; }
    public string Body { get; set; } 
}

static void Main(string[] args)
{
    var mongo = MongoServer.Create();
    var db = mongo.GetDatabase("myDb");
    var col = db.GetCollection<BsonDocument>("myCollection");
    var myinstance = new myClass();
    col.Insert(myinstance);

    var query = Query.And(Query.EQ("_id", new ObjectId("4df06c23f0e7e51f087611f7)));
    var res = col.Find(query);
    foreach (var doc in res)
    {
        var obj = BsonSerializer.Deserialize<myClass>(doc);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,在尝试反序列化文档时,我收到以下异常'意外元素:_id'.

那么我需要以另一种方式反序列化吗?这样做的首选方式是什么?

TIA

索伦

nic*_*kbw 3

您正在使用 ObjectId 搜索给定文档,但是当您保存 MyClass 实例时,您没有提供 Id 属性,因此驱动程序将为您创建一个(您可以通过添加 [BsonId] 属性来使任何属性成为 id)它),当您检索该文档时,您没有 ID,因此您会收到反序列化错误。

您可以像 Chris 所说的那样将 BsonIgnorExtraElements 属性添加到类中,但是您实际上应该将 ObjectId 类型的 Id 属性添加到您的类中,显然您需要 Id (因为您在查询中使用它)。由于 _id 属性是为主键保留的,因此您只能检索单个文档,因此最好像这样编写查询:

col.FindOneById(new ObjectId("4df06c23f0e7e51f087611f7"));
Run Code Online (Sandbox Code Playgroud)

事实上,一旦检索文档,您就会反序列化为 MyClass 实例,这有助于强类型化集合,因此在创建集合实例时,您可以执行此操作

var col = db.GetCollection<MyClass>("myCollection");
Run Code Online (Sandbox Code Playgroud)

这样,当您使用 FindOneById 方法检索文档时,驱动程序将为您处理反序列化,将它们放在一起(假设您将 Id 属性添加到类中),您可以编写

var col = db.GetCollection<MyClass>("myCollection");
MyClass myClass = col.FindOneById(new ObjectId("4df06c23f0e7e51f087611f7"));
Run Code Online (Sandbox Code Playgroud)

最后要注意的一点是,由于 _id 属性是由驱动程序在保存时为您创建的,如果您将其保留在 MyClass 实例中,那么每次保存该文档时,您都会获得一个新的 Id,从而获得一个新文档,因此如果您保存了 n 次,您将拥有 n 个文档,这可能不是您想要的。