2011-06-09 27 views
5

我試圖堅持一個對象到MongoDB中,使用下面的代碼位:「意外元素:XX」期間反序列化的MongoDB C#

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); 
    } 
} 

不過,我得到下面的異常「意外的元素:_id '試圖反序列化文檔時。

那麼我需要以另一種方式反序列化?這樣做的首選方式是什麼?

TIA

瑟倫

回答

3

您正在使用ObjectId搜索給定的文檔,但是當您保存MyClass的實例時,您沒有提供Id屬性,因此驅動程序將爲您創建一個(您可以通過添加[ BsonId]屬性),當您檢索該文檔時,您沒有Id,因此會出現反序列化錯誤。

如Chris所說,您可以將BsonIgnorExtraElements屬性添加到類中,但是您應該真的將類型爲ObjectId的Id屬性添加到您的類中,顯然需要Id(因爲您在查詢中使用它)。由於_id屬性保留主鍵,你永遠只能去檢索單個文件,所以你會過得更好寫你這樣的查詢:

col.FindOneById(new ObjectId("4df06c23f0e7e51f087611f7")); 

您反序列化到的實例的事實MyClass的,一旦你檢索文檔適合於強類型的集合,因此在其中創建集合的一個實例,你可以做到這一點

var col = db.GetCollection<MyClass>("myCollection"); 

,這樣,當您檢索使用FindOneById方法文檔司機會照顧的反序列化爲你把它放在一起(只要你將Id屬性添加到類中)你可以寫

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

最後一點要注意,如通過驅動程序爲您創建的保存_id屬性,如果你要離開它關閉你的MyClass的實例,每次你保存的文件,你會時間得到一個新的Id,因此一個新的文檔,所以如果你保存n次,你會有n個文檔,這可能不是你想要的。

0

嘗試增加_id上您的課。 這通常發生在您的課程沒有文檔中所有字段的成員時。

public class myClass 
{ 
    public ObjectId _id { get; set; } 
    public string Heading { get; set; } 
    public string Body { get; set; } 
} 
+0

這可以工作,但使用Id更像Chris Nicola提出的C#風格。 – foolshat 2012-09-04 19:43:17

3

Projapati的答案略有變化。第一個Mongo將會愉快地將id值反序列化到一個名爲Id的屬性,它更具chsarp-ish。但是,如果您只是檢索數據,則不一定需要這樣做。

您可以將[BsonIgnoreExtraElements]添加到您的班級,它應該工作。這將允許您返回一部分數據,非常適合查詢和查看模型。