सवाल DbSet.Attach (इकाई) बनाम DbContext.Entry (इकाई) .State = EntityState.Modified


जब मैं एक अलग परिदृश्य में हूं और क्लाइंट से एक डीटीओ प्राप्त करता हूं जिसे मैं सहेजने के लिए किसी इकाई में मैप करता हूं, तो मैं यह करता हूं:

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

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

या मुझे एटीच विधि का उपयोग क्यों करना चाहिए जब EntityState.Modified पहले से ही इकाई को जोड़ता है?


76
2018-06-22 19:03


मूल


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


जवाब:


जब तुम करोगे 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; जिससे सभी गुण / कॉलम अपडेट हो जाएंगे)

प्रासंगिक दस्तावेज: जोड़ें / संलग्न करें और इकाई राज्य

कोड उदाहरण

मान लें कि आपके पास निम्न इकाई है:

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.

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

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


184
2018-06-22 19:24



विवरण के साथ अच्छा जवाब! - Elisabeth
ईएफ इस तरह से WHERE खंड उत्पन्न नहीं करता है। यदि आपने नई (यानी नई इकाई ()) के साथ बनाई गई इकाई को संलग्न किया है और इसे संशोधित करने के लिए सेट किया है तो आपको आशावादी लॉक के कारण सभी मूल फ़ील्ड सेट करना होगा। अद्यतन क्वेरी में जेनरेट किए गए WHERE क्लॉज में आमतौर पर सभी मूल फ़ील्ड होते हैं (न केवल आईडी) ताकि यदि आप ऐसा नहीं करते हैं तो ईएफ एक समवर्ती अपवाद फेंक देगा। - bubi
@budi: आपकी प्रतिक्रिया के लिए धन्यवाद। मैं सुनिश्चित करने के लिए फिर से परीक्षण किया, और एक मूल इकाई के लिए, जैसा कि मैंने वर्णन किया है, यह व्यवहार करता है WHERE खंड जिसमें केवल प्राथमिक कुंजी है, और बिना किसी सहमति के चेक। समवर्ती जांच करने के लिए, मुझे एक कॉलम को एक समवर्ती टोकन या पंक्तिवृत्त के रूप में स्पष्ट रूप से कॉन्फ़िगर करने की आवश्यकता है। उस मामले में, WHERE खंड में केवल प्राथमिक कुंजी और समवर्ती टोकन कॉलम होगा, सभी फ़ील्ड नहीं। यदि आपके परीक्षण अन्यथा दिखाए जाते हैं, तो मुझे इसके बारे में सुनना अच्छा लगेगा। - sstan
मैं गतिशील रूप से चुड़ैल संपत्ति को कैसे संशोधित कर सकता हूं? - Navid_pdp11
@ Navid_pdp11 DbContext.Entry(person).CurrentValues तथा DbContext.Entry(person).OriginalValues। - Shimmy


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


0
2017-09-15 07:27