2010-10-13 12 views
117

मैं हाल ही में एंटीटी फ्रेमवर्क 4 के साथ काम कर रहा हूं, और ObjectSet.Attach, और ObjectSet.AddObject का उपयोग करने के लिए थोड़ा उलझन में हूं।इकाई फ्रेमवर्क 4 - AddObject बनाम संलग्न

मेरी समझ से

:

  • "अटैच करें" जब एक इकाई पहले से प्रणाली
  • उपयोग "AddObject" में मौजूद है जब एक नया इकाई
  • बनाने

तो, अगर मैं 'का उपयोग एम एक नया व्यक्ति बनाना, मैं यह करता हूं।

var ctx = new MyEntities(); 
var newPerson = new Person { Name = "Joe Bloggs" }; 
ctx.Persons.AddObject(newPerson); 
ctx.SaveChanges(); 

तो मैं हूँ एक मौजूदा व्यक्ति को संशोधित करने, मैं यह नहीं:

var ctx = new MyEntities(); 
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" }; 
existingPerson.Name = "Joe Briggs"; 
ctx.SaveChanges(); 

ध्यान रखें, यह एक बहुत ही सरल उदाहरण है। हकीकत में मैं शुद्ध पोको (कोई कोड पीढ़ी) का उपयोग नहीं कर रहा हूं, रिपोजिटरी पैटर्न (सीटीएक्स.पर्सन से निपटें नहीं), और कार्य इकाई (सीटीएक्स सेव करें। सेव चेंज)। लेकिन "कवर के तहत", उपरोक्त मेरे कार्यान्वयन में क्या होता है।

अब, मेरे सवाल का - मैं अभी तक एक परिदृश्य में जहाँ मैं उपयोग करने के लिए संलग्न पड़ा है खोजने के लिए कर रहा हूँ।

मुझे यहां क्या याद आ रही है? हमें अटैच का उपयोग करने की आवश्यकता कब होती है?

संपादित

बस स्पष्ट करने के लिए, मैं उदाहरण जब AddObject (या इसके विपरीत) से अधिक संलग्न उपयोग करने के लिए की की तलाश में हूँ।

संपादित 2

नीचे जवाब सही है (जो मैं स्वीकार किए जाते हैं), लेकिन सोचा था कि मैं एक और उदाहरण है, जहां उपयोगी होगा संलग्न जोड़ना होगा।

के लिए मेरे उपरोक्त उदाहरण में मौजूदा व्यक्ति संशोधित करने के लिए, दो प्रश्न वास्तव में निष्पादित किए जा रहे हैं।

व्यक्ति (.SingleOrDefault) को पुनर्प्राप्त करने के लिए, और दूसरा अद्यतन (.SaveChanges) करने के लिए।

अगर (किसी कारण से), मुझे पहले से ही पता था कि "जो ब्लॉग्स" सिस्टम में मौजूद था, तो उसे पहले पाने के लिए अतिरिक्त पूछताछ क्यों करें? मैं यह कर सकता था:

var ctx = new MyEntities(); 
var existingPerson = new Person { Name = "Joe Bloggs" }; 
ctx.Persons.Attach(existingPerson); 
ctx.SaveChanges(); 

इसके परिणामस्वरूप केवल एक अपडेट स्टेटमेंट निष्पादित किया जा रहा है।

+0

संलग्नक एमवीसी में अब भी उपयोग किया जाता है जब मॉडलों को सीधे ईएफ पर वापस रखा जाता है। बहुत अच्छी तरह से काम करता है और कोड लाइनों का एक टन बचाता है। – ppumkin

उत्तर

146

ObjectContext.AddObject और ObjectSet.AddObject:
AddObject विधि नव निर्मित वस्तुओं ऐसा जोड़ने के लिए है नहीं डेटाबेस में मौजूद हैं।इकाई स्वचालित रूप से जेनरेट की गई अस्थायी EntityKey और इसकी एंटिटीस्टेट पर सेट की जाएगी जोड़ा गया। जब SaveChanges को कॉल किया जाता है, तो यह ईएफ को स्पष्ट होगा कि इस इकाई को डेटाबेस में डालने की आवश्यकता है।

ObjectContext.Attach और ObjectSet.Attach:
दूसरी ओर, संलग्न संस्थाओं कि पहले से ही मौजूद डेटाबेस में के लिए प्रयोग किया जाता है। एंटिटीस्टेट को जोड़ने के बजाय, में परिणाम संलग्न करें एंटीटीस्टेट, जिसका अर्थ है कि यह संदर्भ से जुड़ा हुआ होने के बाद से नहीं बदला है। ऑब्जेक्ट्स जो आप संलग्न कर रहे हैं उन्हें डेटाबेस में मौजूद माना जाता है। यदि आप संलग्न होने के बाद ऑब्जेक्ट्स को संशोधित करते हैं, तो जब आप SaveChanges को कॉल करते हैं तो EntityKey का मान डीबी तालिका में अपनी मिलान आईडी ढूंढकर उपयुक्त पंक्ति को अपडेट (या हटा) करने के लिए उपयोग किया जाता है।

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

उदाहरण के लिए, मान लें कि आपके व्यक्ति इकाई पतों नाम के एक नेविगेशन संपत्ति जो पता इकाई का एक संग्रह है है करते हैं। मान लीजिए कि आप संदर्भ से दोनों वस्तुओं को पढ़ लिया है, लेकिन वे एक दूसरे से संबंधित नहीं हैं और आप इसे इसलिए बनाना चाहते हैं:

var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" }; 
var myAddress = ctx.Addresses.First(a => a.PersonID != existingPerson.PersonID); 
existingPerson.Addresses.Attach(myAddress); 
// OR: 
myAddress.PersonReference.Attach(existingPerson) 
ctx.SaveChanges(); 
+0

उत्तर के लिए धन्यवाद, मैं दो (उर्फ पहले दो पैराग्राफ) की परिभाषा को समझता हूं। लेकिन मैं एक परिदृश्य को समझ नहीं पा रहा हूं जहां मुझे अटैच का उपयोग करने की आवश्यकता है। आपका अंतिम पैराग्राफ वास्तव में मुझे समझ में नहीं आता है (मूल रूप से पहले दो पैराग्राफ के संयोजन की तरह पढ़ता है), क्या आप मुझे एक उदाहरण दे सकते हैं कि मैं अपने उपरोक्त परिदृश्य में "अटैच" का उपयोग कहां करूंगा? यह वास्तव में मैं क्या देख रहा हूँ - उदाहरण, परिभाषा नहीं। हालांकि वास्तव में अपने समय की सराहना करते हैं। :) – RPM1984

+1

कोई समस्या नहीं, मैंने पिछले पैराग्राफ को स्पष्ट करने के लिए एक कोड स्निपेट जोड़ा है, जैसा कि आप देख सकते हैं कि हमारे पास 2 असंबद्ध वस्तुएं हैं और अटैच हमें एक-दूसरे से जोड़ने में हमारी सहायता करें। दूसरा उदाहरण संदर्भ में वापस "अलग इकाई" संलग्न करने के लिए अटैच() विधि का उपयोग करना होगा (संदर्भ में वापस संलग्न करने के लिए अलग-अलग कारण हो सकते हैं) –

+0

हाँ, अब मुझे मिला। मैंने अभी ईएफ 4 (जूली लर्मन द्वारा) पर एक टेकएड vid देखा, जिसने एक उदाहरण दिखाया। आपके पास एक ऐसी इकाई हो सकती है जिसे आपने किसी क्वेरी से पुनर्प्राप्त नहीं किया है (यानी यह डिस्कनेक्ट है), लेकिन आप जानते हैं कि यह मौजूद है, इसलिए आप उस इकाई पर अद्यतन करने के लिए अटैचमेंट का उपयोग करते हैं। समझ में आता है, हालांकि मैं अभी भी एक परिदृश्य को कल्पना करने के लिए संघर्ष कर रहा हूं जहां आपके पास "डिस्कनेक्ट" इकाई होगी। आपकी सहायता के लिए धन्यवाद. – RPM1984

-8

केवल प्राथमिक कुंजी की बात कर के बजाय संलग्न बारे में क्या?

यानी:

var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" }; 
var myAddress = ctx.Addresses.First(a => a.PersonID != existingPerson.PersonID); 
existingPerson.AddressId = myAddress.Id // not -> existingPerson.Addresses.Attach(myAddress); 
// OR: 
myAddress.Person.Id = existingPerson.Id // not -> myAddress.PersonReference.Attach(existingPerson); 
ctx.SaveChanges(); 
23

यह एक देर से प्रतिक्रिया है, लेकिन यह दूसरों है कि इस पाने में आपकी मदद कर सकता है।

असल में, "डिस्कनेक्ट" इकाई तब हो सकती है जब आप "उपयोग" दायरे के बाहर किसी इकाई का उपयोग करते हैं।

Employee e = null; 

using (var ctx = new MyModelContainer()) 
{ 
    e = ctx.Employees.SingleOrDefault(emp => emp .....); 
} 

using (var ctx2 = new MyModelContainer()) 
{ 
    e; // This entity instance is disconnected from ctx2 
} 

यदि आप किसी अन्य "का उपयोग" गुंजाइश तो "ई" चर डिस्कनेक्ट कर दिया जाएगा, क्योंकि यह पिछले "का उपयोग" गुंजाइश के लिए और पिछले "का उपयोग" गुंजाइश नष्ट हो जाता है तो "ई" के बाद से संबंध रखता है डाल देते हैं तो कट जाने पर ।

इस तरह मैं इसे समझता हूं।

+2

का आनंद लें Tchi का उदाहरण एक उत्कृष्ट और सरल उदाहरण है - हाँ, कर्मचारी चर को बाहर घोषित किया जाना चाहिए। ई। एड्रेस का प्रयास करें।दायरे के बाहर सड़क और एक शून्य संदर्भ अपवाद पॉप-अप देखें। यदि आप संलग्न करते हैं तो आवेदन को दूसरे दायरे में कर्मचारी के लिए डीबी पर वापस जाना होगा। – Steve

6

इस से Programming Entity Framework: DbContext

एक इकाई है कि संदर्भ द्वारा ट्रैक न होने पर निकालें एक InvalidOperationException फेंक दिया हो जाएंगी कॉलिंग एक उद्धरण है। इकाई फ्रेमवर्क इस अपवाद को फेंकता है क्योंकि यह स्पष्ट नहीं है कि आप जिस को निकालने का प्रयास कर रहे हैं, वह मौजूदा इकाई है जिसे हटाए जाने के लिए चिह्नित किया जाना चाहिए या एक नई इकाई जिसे अभी अनदेखा किया जाना चाहिए। इस कारण से, हम डिस्कनेक्ट की गई इकाई को हटाए गए के रूप में चिह्नित करने के लिए निकालें का उपयोग नहीं कर सकते हैं; हमें इसे पहले संलग्न करने की आवश्यकता है।

private static void TestDeleteDestination() 
{ 
    Destination canyon; 
    using (var context = new BreakAwayContext()) 
    { 
     canyon = (from d in context.Destinations 
     where d.Name == "Grand Canyon" 
     select d).Single(); 
    } 
    DeleteDestination(canyon); 
} 
private static void DeleteDestination(Destination destination) 
{ 
    using (var context = new BreakAwayContext()) 
    { 
     context.Destinations.Attach(destination); 
     context.Destinations.Remove(destination); 
     context.SaveChanges(); 
    } 
} 

TestDeleteDestination विधि एक ग्राहक आवेदन सर्वर से एक मौजूदा गंतव्य प्राप्त करते समय और उसके बाद सर्वर पर DeleteDestination विधि करने के लिए इसे पारित simulates। DeleteDestination विधि संदर्भ को यह जानने के लिए अटैच विधि का उपयोग करती है कि यह एक मौजूदा गंतव्य है। फिर हटाने के लिए मौजूदा गंतव्य को हटाने के लिए

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