2015-06-22 6 views
66

जब मैं एक अलग परिदृश्य में हूं और क्लाइंट से एक डीटीओ प्राप्त करता हूं जिसे मैं सहेजने के लिए किसी इकाई में मैप करता हूं, तो मैं यह करता हूं:DbSet.Attach (इकाई) बनाम DbContext.Entry (इकाई) .State = EntityState.Modified

context.Entry(entity).State = EntityState.Modified; 
context.SaveChanges(); 

फिर क्या है के लिए DbSet.Attach(entity)

या कारण है कि मैं .Attach विधि जब EntityState.Modified पहले से ही इकाई देता इस्तेमाल करना चाहिए?

+0

बेहतर कुछ संस्करण जानकारी जोड़ें, इससे पहले पूछा गया है। मैं स्पष्ट नहीं हूं कि यह एक नया सवाल है। –

उत्तर

158

जब आप context.Entry(entity).State = EntityState.Modified; करते हैं, तो आप न केवल DbContext पर इकाई को जोड़ रहे हैं, आप पूरी इकाई को गंदे के रूप में चिह्नित कर रहे हैं। इसका अर्थ यह है कि जब आप context.SaveChanges() करते हैं, तो ईएफ एक अद्यतन कथन उत्पन्न करेगा जो सभी इकाई के फ़ील्ड अपडेट करेगा।

यह हमेशा वांछित नहीं है।

दूसरी ओर, DbSet.Attach(entity) यह गंदा अंकन के बिना संदर्भ को इकाई जुड़ जाता है। यह context.Entry(entity).State = EntityState.Unchanged;

कर जब इस तरह से संलग्न, जब तक आप तो इकाई पर एक संपत्ति अद्यतन करने के लिए आगे बढ़ने के लिए बराबर है, अगली बार जब आप context.SaveChanges() फोन, एफई इस इकाई के लिए एक डेटाबेस अद्यतन उत्पन्न नहीं करेगा।

भले ही आप किसी इकाई को अपडेट करने की योजना बना रहे हों, अगर इकाई में बहुत से गुण (डीबी कॉलम) हैं, लेकिन आप केवल कुछ अपडेट करना चाहते हैं, तो आपको DbSet.Attach(entity) करने के लिए लाभकारी लगेगा, और फिर केवल उन कुछ गुणों को अपडेट करें जिन्हें अद्यतन करने की आवश्यकता है। इस तरह से ऐसा करना ईएफ से एक अधिक कुशल अद्यतन कथन उत्पन्न करेगा। ईएफ केवल आपके द्वारा संशोधित गुणों को अपडेट करेगा (context.Entry(entity).State = EntityState.Modified; के विपरीत जो सभी गुण/कॉलम अपडेट किए जाएंगे)

प्रासंगिक दस्तावेज: Add/Attach and Entity States

कोड उदाहरण

मान लीजिए कि आप निम्नलिखित इकाई करते हैं:

public class Person 
{ 
    public int Id { get; set; } // primary key 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

अपने कोड इस तरह दिखाई देता है:

context.Entry(personEntity).State = EntityState.Modified; 
context.SaveChanges(); 

एसक्यूएल कुछ इस तरह दिखेगा उत्पन्न:

UPDATE person 
SET FirstName = 'whatever first name is', 
    LastName = 'whatever last name is' 
WHERE Id = 123; -- whatever Id is. 

ध्यान दें कि उपरोक्त अद्यतन कथन सभी कॉलम अपडेट करेगा, भले ही आपने वास्तव में मूल्यों को बदल दिया हो या नहीं।

इसके विपरीत, यदि आपके कोड "सामान्य" का उपयोग करता है इस तरह संलग्न करें:

context.People.Attach(personEntity); // State = Unchanged 
personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty. 
context.SaveChanges(); 

तब उत्पन्न अद्यतन बयान अलग है:

UPDATE person 
SET FirstName = 'John' 
WHERE Id = 123; -- whatever Id is. 

आप देख सकते हैं, अद्यतन बयान केवल उन मानों को अद्यतन करता है जो वास्तव में संदर्भ में इकाई को संलग्न करने के बाद बदल दिए गए थे। आपकी तालिका की संरचना के आधार पर, इसका सकारात्मक प्रदर्शन प्रभाव हो सकता है।

अब, जो विकल्प आपके लिए बेहतर है, वह पूरी तरह से निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं।

+9

विवरण के साथ अच्छा जवाब! – Elisabeth

+0

ईएफ इस तरह से WHERE खंड उत्पन्न नहीं करता है। यदि आपने नई (यानी नई इकाई()) के साथ बनाई गई इकाई को संलग्न किया है और इसे संशोधित करने के लिए सेट किया है तो आपको आशावादी लॉक के कारण सभी मूल फ़ील्ड सेट करना होगा। अद्यतन क्वेरी में जेनरेट किए गए WHERE क्लॉज में आमतौर पर सभी मूल फ़ील्ड होते हैं (न केवल आईडी) ताकि यदि आप ऐसा नहीं करते हैं तो ईएफ एक समवर्ती अपवाद फेंक देगा। – bubi

+1

@budi: आपकी प्रतिक्रिया के लिए धन्यवाद। मैंने सुनिश्चित करने के लिए फिर से परीक्षण किया है, और एक मूल इकाई के लिए, जैसा कि मैंने वर्णित किया है, वही व्यवहार करता है, जिसमें 'प्राथमिक' कुंजी केवल प्राथमिक कुंजी होती है, और बिना किसी सहमति के चेक के। समवर्ती जांच करने के लिए, मुझे एक कॉलम को एक समवर्ती टोकन या पंक्तिवृत्त के रूप में स्पष्ट रूप से कॉन्फ़िगर करने की आवश्यकता है। उस स्थिति में, 'WHERE' खंड में केवल प्राथमिक कुंजी और समवर्ती टोकन कॉलम होगा, न कि सभी फ़ील्ड। यदि आपके परीक्षण अन्यथा दिखाए जाते हैं, तो मुझे इसके बारे में सुनना अच्छा लगेगा। – sstan

0

जब आप DbSet.Update विधि का उपयोग करते हैं, तो इकाई फ्रेमवर्क आपकी इकाई के सभी गुणों को EntityState.Modified के रूप में चिह्नित करता है, इसलिए उन्हें ट्रैक करता है। यदि आप केवल अपनी कुछ संपत्तियों को बदलना चाहते हैं, तो उनमें से सभी नहीं, DbSet.Attach का उपयोग करें। यह विधि आपकी सभी गुण EntityState.Unchanged बनाती है, इसलिए आपको अपनी गुणों को बनाना होगा जिन्हें आप EntityState.Modified अपडेट करना चाहते हैं। इस प्रकार जब ऐप DbContext.SaveChanges पर जाता है, तो यह केवल संशोधित गुणों को संचालित करेगा।

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