2011-08-30 12 views
23

का उपयोग कर MongoDB वे upserts उल्लेख के आधिकारिक दस्तावेज में, तो यह वास्तव में अच्छा होगा बजाय एक Upsert आदेश लिखने के लिए:Upserting अधिकारी सी # चालक

if (_campaignRepo.Exists(camp)) 
{ 
    _campaignRepo.DeleteByIdAndSystemId(camp); 
} 

_campaignRepo.Save(camp); 

कुछ है जिस पर कि तर्क लागू करेगा यदि संभव हो तो डीबी स्तर। तो अगर कोई है तो अपरिवर्तित करने का तरीका क्या है?

उत्तर

25

निम्नलिखित कोड एक काम app से है:

weekplanStore.Update(
    Query.EQ("weekNumber", week), 
    Update.Replace(rawWeekPlan), 
    UpdateFlags.Upsert); 

weekplanStore मेरी MongoDB संग्रह है, और कोड दस्तावेज अपडेट करेगा या पहले तर्क में क्वेरी के साथ पाया अगर कोई नहीं मिला तो एक नया डालें। "चाल" UpdateFlags.Upsert संशोधक का उपयोग करना है।

rawWeekPlan वस्तु डाला जाता है या अद्यतन है, और निम्न प्रकार है:

private class RawWeekPlan 
{ 
    public ObjectId id; 
    public int weekNumber; 
    public WeekPlanEntry[] entries; 
} 

और स्वचालित रूप से चालक द्वारा bson में बदल गया।

+0

क्या यह नेस्टेड संग्रहों के लिए काम करता है? क्या आपने इसे आजमाया है? क्योंकि यह मेरे मामले में उनके लिए काम नहीं करता –

+0

पता नहीं है। मैंने नेस्टेड संग्रहों पर इसकी कोशिश नहीं की है। –

+0

समस्या आईडी-एस में है। मैंने एक और थ्रेड –

39

MongoDB C# ड्राइवर के संस्करण 2 लिखने के आदेशों में IsUpsert ध्वज सेट करने की आवश्यकता है। यह उदाहरण एक संपूर्ण दस्तावेज़ को अपरिवर्तित करेगा।

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } }; 
var result = await collection.ReplaceOneAsync(
    filter: new BsonDocument("_id", 123), 
    options: new UpdateOptions { IsUpsert = true } 
    replacement: newDoc); 

संस्करण MongoDB सी # चालक की 1Save आदेश के भीतर इस तर्क लागू करता है।

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } }; 
collection.Save(newDoc); 

विधि सहेजें सम्मिलित और अद्यतन का एक संयोजन है। यदि दस्तावेज़ के आईडी सदस्य के पास कोई मान है, तो इसे दस्तावेज़ पर एक मौजूदा दस्तावेज़ माना जाता है और कॉल पर अपडेट सहेजें (उपरोक्त ध्वज सेट करना केवल यह वास्तव में एक नया दस्तावेज़ है)। अन्यथा यह एक नया दस्तावेज़ माना जाता है और आईडी सदस्य को नए जेनरेट किए गए अद्वितीय मूल्य को निर्दिष्ट करने के बाद कॉल सहेजें।

संदर्भ: http://mongodb.github.io/mongo-csharp-driver/1.11/driver/#save-tdocument-method

नोट: यह हालांकि ईद क्षेत्र के समुचित मानचित्रण की जरूरत है। कि यहाँ पर और जानकारी: http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property

+0

यह अब नई एपीआई के साथ संभव नहीं है। –

+0

अपडेट किया गया। हालांकि मुझे लगता है कि नए एपीआई ने अप्सर्ट कमांड को इस्तेमाल करने के लिए कड़ी मेहनत की है। –

+0

यदि नई डॉक्स आईडी शून्य है, तो फ़िल्टर को क्या पास हो जाता है, यानी यह एक सम्मिलित है? बस एक खाली बीएसओ दस्तावेज़? – BenCr

5

आप नियमित रूप से अद्यतन आदेश का उपयोग कर सकते हैं, लेकिन सिर्फ यह Upsert अद्यतन झंडा

MongoCollection collection = db.GetCollection("matches"); 
var query = new QueryDocument("recordId", recordId); 

var update = Update.Set("FirstName", "John").Set("LastName","Doe"); 
matchCollection.Update(query, update, UpdateFlags.Upsert, SafeMode.False); 

कि कोड एक काम कर आवेदन (स्पष्टता के लिए संक्षिप्त)

21

की v2.0 से शुरू से अनुकूलित है पारित ड्राइवर में एक नया एसिंक-केवल एपीआई है। पुरानी एपीआई का उपयोग अब नहीं किया जाना चाहिए क्योंकि यह नई एपीआई पर अवरुद्ध मुखौटा है और इसे हटा दिया गया है।

Hamster hamster = ... 
var replaceOneResult = await collection.ReplaceOneAsync(
    doc => doc.Id == hamster.Id, 
    hamster, 
    new UpdateOptions {IsUpsert = true}); 

आप देख सकते हैं कि क्या आपरेशन एक डालने था या:

एक दस्तावेज Upsert को वर्तमान में सुझाया गया तरीका बुला और ReplaceOneAsync का इंतजार कर IsUpsert ध्वज के साथ चालू है और है कि प्रासंगिक दस्तावेज़ से मेल खाता है एक फिल्टर के द्वारा होता है ReplaceOneResult.MatchedCount पर देखकर एक अपडेट:

+0

पर एक प्रश्न पूछा, मैं ReplaceOneAsync का उपयोग करने की कोशिश कर रहा हूं लेकिन यह एक अपवाद फेंकता है: "एलिमेंट नेम" मान्य नहीं है ", मैं अद्यतन के लिए फ़िल्टर का उपयोग कर रहा हूं, यह काम करता है लेकिन प्रतिस्थापन के साथ नहीं। क्या आप मेरी मदद कर सकते हैं? –

संबंधित मुद्दे