2012-03-08 2 views
11

मेरे तालिका Sections (SQL सर्वर) ID एक प्राथमिक कुंजी (int, identity) और SortIndex स्तंभ (पूर्णांक) के रूप में है के द्वारा संशोधित किया गया है अपडेट नहीं होता।इकाई की रूपरेखा मूल्य जो प्रयोजनों छँटाई के लिए एक ट्रिगर

डेटाबेस में एक ट्रिगर है जो प्रत्येक INSERT पर SortIndex := ID सेट करता है। जाहिर है, मैं दो पंक्तियों के मानों को स्वैप करके, सॉर्टिंग इंडेक्स को बाद में बदलना चाहता हूं।

मैं एंटिटी फ्रेमवर्क का उपयोग कर डेटा तक पहुंचता हूं, सभी एमवीसी 3 वेब एप्लिकेशन के साथ।

समस्या यह है कि, तालिका में कोई नई वस्तु डालने के बाद इकाई फ्रेमवर्क SortIndex के मान को अपडेट नहीं करता है। यह सभी डेटा को भी कैश करता है, इसलिए इस तालिका से सभी ऑब्जेक्ट्स प्राप्त करने के लिए निम्न कॉल इस ऑब्जेक्ट के लिए गलत SortIndex मान भी देगा।

मैंने EDMX में इस कॉलम के लिए StoreGeneratedPattern बदलने की कोशिश की। यह बहुत अच्छा और सुरुचिपूर्ण प्रतीत होता है लेकिन समस्या का समाधान नहीं करता है।

यदि मैं Identity पर सेट करता हूं, तो यह ईएफ को मूल्य को सही तरीके से अपडेट करने का कारण बनता है, लेकिन यह केवल पढ़ा जाता है (बदलने की कोशिश करते समय अपवाद फेंक दिया जाता है)। इसे Computed पर सेट करना समान है, लेकिन अपवाद के बजाय मूल्यों को डीबी को नहीं लिखा गया है।

मैं अगर मैं एक वस्तु डालने के बाद इसे उपयोग करने की आवश्यकता एफई वस्तु हर बार पुन: कर सकते हैं, बस ऐसा करके:

DatabaseEntities db = new DatabaseEntities() 

लेकिन यह मेरे लिए बदसूरत वैकल्पिक हल की तरह लगता है।

इस समस्या का समाधान क्या है?

स्पष्ट रूप से कुछ, मुझे insert के बाद कुछ कार्रवाई करने की आवश्यकता नहीं है (और यह जोखिम लेना कि यह भूल गया है और अनजान है) को प्राथमिकता दी जाती है।

+0

संभावित डुप्लिकेट: http://stackoverflow.com/questions

अगर कोई रुचि है, यह, एफई आंशिक वर्ग और उसके बाद आंशिक विधि OnContextCreated जोड़ने के लिए यहाँ की तरह से कुछ और करने के लिए MergeOption डिफ़ॉल्ट बनाने के लिए संभव है/5445243/पुनः लोड-फ़ील्ड-वैल्यू-संशोधित-इन-डीबी-बाय-ट्रिगर-बाद-सम्मिलित-अद्यतन –

+0

यह समान है, लेकिन ऐसा लगता है कि उसे ऐसा फ़ील्ड है जिसे उसे लिखने की आवश्यकता नहीं है। "गणना" उसके लिए ठीक होना चाहिए। यह कुछ बग के कारण काम नहीं करता है। – Arek

उत्तर

15

कम StoreGeneratedPattern में अर्थ है: मूल्य की दुकान द्वारा नियंत्रित किया जाता है और अपने आवेदन इसे संशोधित कभी नहीं होगा। इस मामले में आपको SaveChanges पर कॉल करने के बाद स्वचालित रूप से स्टोर जेनरेट वैल्यू मिलेगा।

आप StoreGeneratedPattern उपयोग नहीं करते हैं आप मूल्य नहीं मिलेगा और आप अपने इकाई ताज़ा करने के लिए किसी अन्य क्वेरी निष्पादन के लिए मजबूर करना होगा। उदाहरण के लिए आप कर सकते हैं:

objectContext.Refresh(RefreshMode.StoreWins, yourSection); 

आम तौर पर स्थितियों में, जहां आप ट्रिगर और आवेदन के माध्यम से दोनों डेटाबेस में मान अद्यतन करने की आवश्यकता एफई (और शायद भी अन्य ORM उपकरण) के साथ बहुत अच्छी तरह से नहीं खेलते हैं।

+0

'रीफ्रेश' कोड के लिए धन्यवाद, यह ईएफ ऑब्जेक्ट को पुनर्निर्मित करने से बेहतर दिखता है। दुर्भाग्य से मैं अपनी प्रतिष्ठा के साथ वोट नहीं दे सकता। – Arek

+0

@Arek आप उत्तर –

+0

स्वीकार कर सकते हैं मुझे पता है कि मैं स्वीकार कर सकता हूं, लेकिन मैं यहां कुछ अन्य संभावित समाधानों का परीक्षण कर रहा हूं, अभी तक नहीं। – Arek

0

क्या आप जानते हैं कि आप उसी कॉलम में फिर से उसी कॉलम में काम करेंगे या नहीं?

मैं प्रति अनुरोध परिदृश्य के संदर्भ का उपयोग करता हूं, जो आमतौर पर आपको कई समस्याएं प्राप्त करता है, क्योंकि प्रत्येक अनुरोध के साथ एक नया ईएफ संदर्भ बनाया जाता है, इसलिए प्रति अनुरोध के बाद आपके पास एक नया डेटा होता है।

लंबे समय तक रहने वाले संदर्भ के साथ, आपके द्वारा वर्णित विसंगतियों को विकसित कर सकते हैं।

वैसे भी स्टोर जेनरेटेड पैटर्न गणना करने के लिए सेट किया जाना चाहिए सही होना चाहिए। लेकिन यह केवल तभी अपडेट होता है जब आप वास्तविक इकाई को संग्रहीत कर रहे हों। यह किसी अन्य इकाई को डालने या अपडेट करके अपडेट नहीं हो रहा है।

http://msdn.microsoft.com/en-us/library/dd296755(v=vs.90).aspx

से

आप एक नई इकाई बनाते हैं या मौजूदा इकाई बदलते हैं, तो परिकलित करने के लिए सेट StoreGeneratedPattern साथ गुण के मूल्यों सर्वर से प्राप्त जब आप अपने आवेदन में SaveChanges विधि कॉल कर रहे हैं। यदि आप अपने अनुप्रयोग में गणना के लिए StoreGeneratedPattern सेट के साथ किसी प्रॉपर्टी को मान निर्दिष्ट करते हैं, तो जब आप SaveChanges विधि को कॉल करते हैं तो मान सर्वर द्वारा जेनरेट किए गए मान के साथ ओवरराइट किया जाएगा।

हम SQL अनुक्रमित GUID के लिए गणना मूल्य विकल्प का उपयोग कर रहे हैं, और यह ठीक काम कर रहा है।

+0

मैं जो कर रहा हूं वह है (1) नई वस्तु जोड़ें, (2) वेबपृष्ठ को अपडेट करने के लिए सॉर्टइंडेक्स द्वारा आदेशित सभी ऑब्जेक्ट प्राप्त करें और वापस करें। तो हाँ, मैं एक ही अनुरोध में फिर से SortIndex का उपयोग कर रहा हूँ। – Arek

+0

और StoreGeneratedPattert = संगणित - यह ऑब्जेक्ट को ठीक से अपडेट करने लगता है, लेकिन मैं अब SortIndex को संशोधित नहीं कर सकता। मैं कोशिश करता हूं, लेकिन जब मैं SaveChanges() पुराने मान बहाल करता हूं। ऐसा लगता है कि ईएफ चुपचाप इन परिवर्तनों को अनदेखा करता है। – Arek

+0

हां, स्टोर जेनरेटेड स्पष्ट रूप से कहता है कि यह स्टोर में जेनरेट किया गया है, इसलिए इसे लिखने में कोई परेशानी नहीं है। शायद आपके लिए सबसे अच्छा इकाई को सेट करना होगा .ortIndex = entity.id केवल सहेजने के बाद, आप इसके साथ काम कर सकते हैं जैसा आप चाहें। –

2

मैं 'Ladislav Mrnka' सटीक होने से इस सवाल का जवाब मिल गया है और यह चिह्नित मान लिया गया। यहां कुछ अन्य कामकाज हैं, जिन्हें मैंने कुछ समाधान खोजने की कोशिश करते हुए पाया। हालांकि, जिस समाधान को मैं ढूंढ रहा था वह आम तौर पर संभव नहीं है।

संभावनाओं में से एक यह बताने के लिए एफई पता StoreGeneratedPattern = Computed स्थापित करने के लिए है, यह मान गणना की जाती है। और फिर, SortIndex के मान को वास्तव में बदलने के लिए एक संग्रहित प्रक्रिया बनाएं। आमतौर पर यह सॉर्टिंग ऑर्डर बदलने के लिए दो पंक्तियों (उन्हें स्वैप) में मानों को बदल देगा। INSERT पर एक ट्रिगर के साथ यह प्रक्रिया डीबी में संगत डेटा की गारंटी देता है। SortIndex में उचित मूल्य सेट के बिना नई पंक्ति बनाना संभव नहीं है, दो ऑब्जेक्ट्स को एक ही मान बनाना संभव नहीं है (जब तक संग्रहित प्रक्रिया में कोई बग न हो) और किसी भी तरह मैन्युअल रूप से मान को तोड़ना संभव नहीं है, क्योंकि इसे संपादित करना संभव नहीं है ईएफ के माध्यम से। एक महान समाधान की तरह लग रहा है।

यह संग्रहित प्रक्रियाओं एफई में कार्य करने के लिए मैप किया गया है करने के लिए आसानी से संभव है।

समस्या, अब एक नई पंक्ति में प्रवेश के लिए ठीक है यह है और एफई ठीक से अपने कैश में डेटा अद्यतन करता है, लेकिन कैश संग्रहीत प्रक्रिया बुला बाद अपडेट नहीं होती। अभी भी कुछ मैन्युअल अपडेट या रीफ्रेश फ़ंक्शन की आवश्यकता है। अन्यथा SortIndex द्वारा क्रमबद्ध वस्तुओं को प्राप्त करने के लिए निम्न कॉल गलत परिणाम देगा।

इसके अलावा, कई इकाइयों के लिए MergeOption = MergeOption.OverwriteChanges सेट करना संभव है, जिससे ईएफ कुछ बेहतर तरीके से डीबी से डेटा अपडेट कर सकता है। ऐसा करने के साथ, इसे डालने या संग्रहित प्रक्रिया को कॉल करने के बाद ऑब्जेक्ट को फिर से पढ़ना संभव है और यह ताज़ा हो जाएगा। हालांकि, db.Section.OrderBy(o => o.SortIndex) के साथ ऑब्जेक्ट्स का संग्रह पढ़ने से गलत सॉर्टिंग ऑर्डर के साथ कैश किए गए परिणाम वापस आ जाएंगे।

public partial class DatabaseEntities 
{ 
    partial void OnContextCreated() 
    { 
     Subsection.MergeOption = MergeOption.OverwriteChanges; 
     Section.MergeOption = MergeOption.OverwriteChanges; 
     Function.MergeOption = MergeOption.OverwriteChanges; 
    } 
} 
+0

धन्यवाद, यह मेरे लिए काम करता है !!! – Rodrigo

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