2011-06-09 17 views
5

मैं कोड की निम्न बिट का उपयोग कर, एक MongoDB में एक वस्तु लागू करने के लिए कोशिश कर रहा हूँ:'अनपेक्षित तत्व: XX' के दौरान अक्रमांकन 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); 
    } 
} 

हालांकि मैं निम्नलिखित अपवाद 'अनपेक्षित तत्व: _ id 'दस्तावेज़ को deserialize करने की कोशिश करते समय।

तो क्या मुझे किसी अन्य तरीके से Deserialize करने की आवश्यकता है ?? ऐसा करने का पसंदीदा तरीका क्या है?

TIA

सोरेन

उत्तर

3

आप ऑब्जेक्टआईडी का उपयोग करके किसी दिए गए दस्तावेज़ की खोज कर रहे हैं, लेकिन जब आप MyClass का एक उदाहरण सहेजते हैं तो आप आईडी आईडी नहीं प्रदान कर रहे हैं ताकि चालक आपके लिए एक बनायेगा (आप किसी भी संपत्ति को आईडी जोड़कर [ BsonId] इसमें विशेषता है), जब आप उस दस्तावेज़ को पुनर्प्राप्त करते हैं तो आपके पास कोई आईडी नहीं है, इसलिए आपको deserialization त्रुटि मिलती है।

क्रिस के रूप में आप कक्षा में BsonIgnorExtraElements विशेषता जोड़ सकते हैं, लेकिन आपको वास्तव में अपनी कक्षा में ऑब्जेक्ट आईडी के आईडी आईडी को जोड़ना चाहिए, आपको स्पष्ट रूप से आईडी की आवश्यकता है (जैसा कि आप इसे अपनी क्वेरी में उपयोग कर रहे हैं)। के रूप में _ id संपत्ति प्राथमिक कुंजी के लिए आरक्षित है, आप केवल कभी एक एकल दस्तावेज़ को पुनः प्राप्त करने तो आप इस तरह आपकी क्वेरी लेखन को बेहतर होगा जा रहे हैं:

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

तथ्य यह है कि आप का एक उदाहरण के लिए कर रहे हैं deserializing MyClass एक बार आप पुनः प्राप्त दस्तावेज़ बख्शी ही दृढ़ता से संग्रह टाइपिंग के लिए है, इसलिए जहां संग्रह का एक उदाहरण बनाने आप इस

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

इतना ख्याल है कि जब आप FindOneById विधि का उपयोग कर दस्तावेज़ पुन: प्राप्त ड्राइवर ले जाएगा क्या कर सकते हैं आप सभी को एक साथ रखने के लिए deserialization की (बशर्ते आप कक्षा में आईडी संपत्ति जोड़ें) आप

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

एक अंतिम बात नोट करने के लिए, हर बार जब आप उस दस्तावेज़ तुम करोगी बचाया लिख ​​सकता है के रूप में _ id संपत्ति चालक द्वारा बचाने पर आप के लिए बनाई गई है, तो आप इसे अपने MyClass उदाहरण बंद छोड़ने के लिए थे, एक नया आईडी प्राप्त करें और इसलिए एक नया दस्तावेज़ प्राप्त करें, इसलिए यदि आपने इसे एन बार सहेजा है तो आपके पास एन दस्तावेज़ होंगे, जो शायद आप नहीं चाहते हैं।

0

को अपनी कक्षा में _ id जोड़ने का प्रयास करें। यह आमतौर पर तब होता है जब आपकी कक्षा में आपके दस्तावेज़ के सभी फ़ील्ड के सदस्य नहीं होते हैं।

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

यह काम करता है, लेकिन आईडी निक का उपयोग सी # शैली के अधिक है क्योंकि क्रिस निकोला ने प्रस्तावित किया था। – foolshat

3

प्रजापति के उत्तर में मामूली बदलाव। पहला मोंगो Id नामक संपत्ति के लिए आईडी मूल्य को खुशी से deserialize करेगा जो अधिक chsarp-ish है। लेकिन अगर आपको डेटा पुनर्प्राप्त कर रहे हैं तो आपको यह करने की ज़रूरत नहीं है।

आप अपनी कक्षा में [BsonIgnoreExtraElements] जोड़ सकते हैं और इसे काम करना चाहिए। यह आपको डेटा के सबसेट को वापस करने की अनुमति देगा, प्रश्नों और दृश्य-मॉडल के लिए अच्छा होगा।