12

एंटिटी फ्रेमवर्क (मेरे मामले में पहले कोड) का उपयोग करके, मेरे पास एक ऑपरेशन है जिसके लिए मुझे SaveBanges को डीबी में एक ऑब्जेक्ट को अपडेट करने के लिए कॉल करने की आवश्यकता है, और फिर SaveChanges को फिर से किसी अन्य ऑब्जेक्ट को अपडेट करने के लिए। (मुझे किसी समस्या को हल करने के लिए पहले SaveChanges की आवश्यकता है जहां EF यह पता नहीं लगा सकता कि कौन सा ऑब्जेक्ट पहले अपडेट करना है)।ईएफ: मैं एक लेनदेन के अंदर दो बार SaveChanges को कैसे कॉल करूं?

using (var transaction = new TransactionScope()) 
{ 
    // Do something 

    db.SaveChanges(); 

    // Do something else 

    db.SaveChanges(); 

    tramsaction.Complete(); 
} 

जब मैं चलने वाले, मैं कह रहा "अंतर्निहित प्रदाता खुला पर विफल" दूसरा SaveChanges कॉल पर एक अपवाद हो,:

मैं कर की कोशिश की। आंतरिक अपवाद का कहना है कि मेरी मशीन पर एमएसडीटीसी सक्षम नहीं है।

अब, मैंने अन्य जगहों को पोस्ट किया है जो वर्णन करते हैं कि एमएसडीटीसी को कैसे सक्षम किया जाए, लेकिन ऐसा लगता है कि मुझे नेटवर्क एक्सेस इत्यादि को सक्षम करने की भी आवश्यकता होगी। यह पूरी तरह से ओवरकिल की तरह लगता है, क्योंकि इसमें कोई अन्य डेटाबेस शामिल नहीं है, चलो अकेले अन्य सर्वर। मैं ऐसा कुछ नहीं करना चाहता जो मेरा पूरा एप्लिकेशन कम सुरक्षित (या धीमा) करने जा रहा है।

निश्चित रूप से ऐसा करने का एक और हल्का तरीका होना चाहिए (आदर्श रूप से एमएसडीटीसी के बिना) ?!

+0

आप एसक्यूएल 2008 का उपयोग कर रहे जोड़ने की जरूरत है? आपके वास्तविक तर्क के आधार पर, आप आगे बढ़ने के बिना कई कनेक्शन खोल सकते हैं। डीटीसी को बुलाए जाने पर यहां एक शानदार पोस्ट तोड़ दी गई है: [लेनदेन का दायरा स्वचालित रूप से एमएसडीटीसी में बढ़ रहा है] (http: // stackoverflow।कॉम/प्रश्न/16908 9 2/लेन-देन-स्वचालित रूप से-एस्केलेटिंग-टू-एमएसडीटीसी-ऑन-मशीनों) –

+0

यदि आप केवल एक लेनदेन में सब कुछ करना चाहते हैं तो सब कुछ एक बार सहेजने या सब कुछ बचाने के बीच क्या अंतर है? दोनों मामलों में या तो सब कुछ बचाया जाएगा या कुछ भी बचाया नहीं जाएगा, इसलिए मुझे एकाधिक बचत का कोई फायदा नहीं दिख रहा है। नीचे दी गई टिप्पणी के अनुसार - एसक्यूएल सर्वर 2005 में एक लेनदेन के भीतर कई कनेक्शन खोलने (यहां तक ​​कि यदि स्रोत समान है) लेनदेन को एक वितरित लेनदेन के रूप में बढ़ावा दिया जाता है। यह एसक्यूएल सर्वर 2008 में सुधार हुआ था, जहां आप प्रोमोशन – Pawel

+0

@markoreta के बिना एक ट्रैक्स के भीतर एक ही डेटासोर्स में एकाधिक कनेक्शन खोल सकते हैं: मैं SQL सर्वर 2012 का उपयोग कर रहा हूं। मेरे पास एकाधिक कनेक्शन नहीं हैं (और चाहते हैं) वास्तव में एमएसडीटीसी का उपयोग नहीं करना चाहता! –

उत्तर

6

शायद यह आपके लेनदेन में उपयोग किए जाने वाले दो अलग-अलग कनेक्शनों के कारण होता है। मैन्युअल रूप से अपने ऑपरेशन के लिए कनेक्शन को नियंत्रित करने का प्रयास करें:

var objectContext = ((IObjectContextAdapter)db).ObjectContext; 

try { 
    object.Context.Connection.Open(); 
    using (var transaction = new TransactionScope()) { 
     // Do something 

     db.SaveChanges(); 

     // Do something else 

     db.SaveChanges(); 

     transaction.Complete(); 
    } 
} finally { 
    objectContext.Connection.Close(); 
} 
+0

यदि यह एक ही डीबीकॉन्टेक्स्ट में है, तो EF6.0 में संदर्भ है। डेटाबेस। बेजिन ट्रान्सएक्शन()। लेकिन यह अलग-अलग काम करता है अगर विभिन्न डीबीसीएन्टेक्स में संचालन। –

7

SaveChanges बुला() के रूप में आप कर रहे हैं के द्वारा उत्पन्न कर रहा है डेटा डेटाबेस और एफई को कायम जाने वाले परिवर्तनों यह सिर्फ बनाया के बारे में भूल करने के लिए।

यह चाल SaveChanges (झूठी) का उपयोग करना है ताकि परिवर्तन डीबी पर बने रहे लेकिन ईएफ परिवर्तनों को नहीं भूलता है जिससे यह लॉगिंग/पुनः प्रयास कर रहा है।

 var scope = new TransactionScope(
      TransactionScopeOption.RequiresNew, 
      new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable } 
     ); 

     using (scope) 
     { 
      Entities context1 = new Entities(); 
      // Do Stuff 
      context1.SaveChanges(false); 

      Entities context2 = new Entities(); 
      // Do Stuff 
      context2.SaveChanges(false); 

      scope.Complete(); 
      context1.AcceptAllChanges(); 
      context2.AcceptAllChanges(); 
     } 

पीएस जैसे ही आपके पास लेन-देन के अंदर एक से अधिक कनेक्शन खुले हैं, यह डीटीसी में बढ़ेगा।

+0

धन्यवाद। यह बेहद सराहनीय लगता है, हालांकि मेरे मामले में मुझे स्थानीय संदर्भ की स्थिति पर कोई परवाह नहीं है, अगर कोई त्रुटि हो, क्योंकि उस मामले में मैं बमबारी कर रहा हूं और वैसे भी संदर्भ को नष्ट कर दूंगा। अभी भी, जानना अच्छा है। –

+0

क्या होगा यदि पहला अपडेट ऑपरेशन ठीक हो जाए लेकिन दूसरा अपडेट ऑपरेशन विफल हो जाए, तो क्या आपका डेटा डीबी में संगत है? –

+0

चूंकि पूरी चीज ट्रांज़ेक्शनस्कोप में लपेटी गई है, तो मुझे उम्मीद करनी चाहिए! –

11

मुझे पता है कि यह देर से उत्तर है लेकिन मुझे इसे साझा करने में उपयोगी लगता है।

अब EF6 में यह आसान है dbContext.Database.BeginTransaction()

इस तरह का उपयोग करके इस acheeve रहे हैं: this

पर

using (var context = new BloggingContext()) 
{ 
    using (var dbContextTransaction = context.Database.BeginTransaction()) 
    { 
     try 
     { 
      // do your changes 
      context.SaveChanges(); 

      // do another changes 
      context.SaveChanges(); 

      dbContextTransaction.Commit(); 
     } 
     catch (Exception) 
     { 
      dbContextTransaction.Rollback(); 
     } 
    } 
} 
अधिक जानकारी देखने के लिए

इसे फिर से आगे

EF6 में है फाइनल के लिए
+0

धन्यवाद, यह और भी पसंद है! –

+0

आपका स्वागत है :) –

+0

आपको केवल रोलबैक की तुलना में कैच ब्लॉक के साथ और अपवाद निगलना चाहिए। लॉग, रीथ्रो, ... –

1

ऊपर चयनित उत्तर, एक टाइपो है। नीचे सही लाइन:

objectContext.Connection.Open(); 

इसके अलावा, System.Data.Entity.Infrastructure के लिए संदर्भ और System.Transactions

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