2011-12-30 12 views
10

EntitySet 'InstanceObjectName' अद्यतन करने के लिए है क्योंकि यह एक DefiningQuery है और कोई तत्व तत्व में मौजूद वर्तमान कार्रवाईDefiningQuery और कोई <DeleteFunction> तत्व <ModificationFunctionMapping> तत्व में मौजूद वर्तमान कार्रवाई का समर्थन करने के

उत्तर

4
का समर्थन करने में असमर्थ

एंटिटी फ्रेमवर्क यह नहीं जानता कि कोई दिया गया दृश्य अद्यतन करने योग्य है या नहीं, इसलिए यह गैर-अद्यतन करने योग्य दृश्य के विरुद्ध क्वेरी उत्पन्न करने के ढांचे के प्रयास के विरुद्ध सुरक्षित होने के लिए तत्व जोड़ता है।

यदि आपका दृश्य अपडेट करने योग्य है तो आप अपने .edmx के स्टोरेजमोडेल अनुभाग के अंदर अपने दृश्य के लिए एंटिटीसेट परिभाषा से तत्व को हटा सकते हैं, और सामान्य अपडेट प्रोसेसिंग किसी अन्य तालिका के साथ काम करेगी।

यदि आपका दृश्य अद्यतन करने योग्य नहीं है, तो आपको "संशोधन फ़ंक्शन मैपिंग" के माध्यम से अद्यतन तर्क प्रदान करना होगा। संशोधन फ़ंक्शन मैपिंग आपके .edmx के संग्रहण मॉडल अनुभाग में परिभाषित फ़ंक्शन को कॉल करता है। उस फ़ंक्शन में आपके डेटाबेस में संग्रहीत प्रक्रिया में नाम और तर्क हो सकते हैं, या आप हमारे .edmx के संग्रहण मॉडल अनुभाग में फ़ंक्शन परिभाषा में सीधे सम्मिलन, अद्यतन या हटाएं लिखने के लिए "परिभाषित आदेश" कर सकते हैं। ।

दो विकल्पों में से, यदि आपका दृश्य अद्यतन करने योग्य है (जो ऐसा लगता है) यह सबसे आसान है कि डिजाइनर द्वारा डाला गया सबसे आसान है।

+1

पुष्टि की, अपनी तालिका पर एक पीके की आवश्यकता है (एक समग्र पीके करेगा)। DefiningQuery को हटाने से चीज़ें बदतर हो जाती हैं। – StuartLC

+0

मुझे यह समस्या है लेकिन यदि मैं ईडीएमएक्स से DefiningQuery अनुभाग को हटा देता हूं, तो अगली बार जब मैं डीबी से मॉडल अपडेट करता हूं तो क्या यह अनुभाग पुन: उत्पन्न हो जाएगा? – Jerry

25

सुनिश्चित करें कि आपकी तालिका में प्राथमिककी है!

3

अद्यतन: मुझे हाल ही में कुछ अपवॉट मिल गए हैं, इसलिए मुझे लगा कि मैं लोगों को सलाह दूंगा कि मैं नीचे दी गई सलाह सबसे अच्छी नहीं है। चूंकि मैंने मूल रूप से पुराने कुंजीहीन डेटाबेस पर एंटीटी फ्रेमवर्क करने के बारे में बात करना शुरू कर दिया है, इसलिए मुझे एहसास हुआ है कि आप एफएआर द्वारा कर सकते हैं सबसे अच्छी बात यह है कि इसे रिवर्स कोड-प्रथम द्वारा किया जाता है। ऐसा करने के तरीके पर कुछ अच्छे लेख हैं। बस उनका पालन करें, और फिर जब आप इसमें कोई कुंजी जोड़ना चाहते हैं, तो कुंजी को "नकली" करने के लिए डेटा एनोटेशन का उपयोग करें।

उदाहरण के लिए, मान लीजिए कि मैं अपनी तालिका Orders जानता हूं, जबकि इसकी प्राथमिक कुंजी नहीं है, केवल प्रति ग्राहक एक ऑर्डर नंबर होने का आश्वासन दिया जाता है। चूंकि वे मेज पर पहले दो स्तंभ हैं, मैं कोड पहले कक्षाएं इस तरह देखने के लिए सेट करेंगे:

[Key, Column(Order = 0)] 
    public Int32? OrderNumber { get; set; } 

    [Key, Column(Order = 1)] 
    public String Customer { get; set; } 

ऐसा करने से, आप मूल रूप से विश्वास है कि वहाँ एक संकुल बना कुंजी में एफई नाटक किया गया है ऑर्डर नम्बर और ग्राहक का। यह आपको अपनी कीलेस टेबल पर आवेषण, अपडेट इत्यादि करने की अनुमति देगा।

यदि आप रिवर्स कोड पहले करने से बहुत परिचित नहीं हैं, तो जाओ और एंटीटी फ्रेमवर्क कोड फर्स्ट पर एक अच्छा ट्यूटोरियल ढूंढें। फिर एक बार जब आप इसके साथ सहज महसूस करते हैं, तो रिवर्स कोड फर्स्ट (जो मौजूदा डेटाबेस के साथ कोड पहले कर रहा है) पर एक पाएं। फिर बस यहां वापस आएं और मेरी मुख्य सलाह फिर से देखें। :)

मूल उत्तर:

पहले: के रूप में अन्य लोगों ने कहा, सबसे अच्छा विकल्प मेज पर एक प्राथमिक कुंजी जोड़ना है। पूर्ण विराम। यदि आप ऐसा कर सकते हैं, तो आगे पढ़ें।

लेकिन यदि आप नहीं कर सकते हैं, या सिर्फ खुद से नफरत करते हैं, तो प्राथमिक कुंजी के बिना इसे करने का एक तरीका है। असल में, हम जो करने जा रहे हैं वह इकाई फ्रेमवर्क से झूठ बोलता है और बताता है कि एक प्राथमिक कुंजी है।

मेरे मामले में, मैं एक विरासत प्रणाली (मूल रूप से एक्सेस करने के लिए पोर्ट किए गए AS400 पर फ्लैट फ़ाइलों और फिर टी-एसक्यूएल पर पोर्ट किया गया) के साथ काम कर रहा था।तो मुझे एक रास्ता खोजना पड़ा। यह मेरा समाधान है। एंटीटी फ्रेमवर्क 6.0 (इस लेखन के रूप में NuGet पर नवीनतम) का उपयोग करके निम्नलिखित मेरे लिए काम किया। समाधान Explorer में अपने .edmx फ़ाइल पर

  1. राइट क्लिक करें। "इसके साथ खोलें ..." चुनें और फिर "एक्सएमएल (टेक्स्ट) संपादक" चुनें। हम यहां ऑटो-जेनरेट कोड को हाथ से संपादित करने जा रहे हैं। इस तरह की एक पंक्ति के लिए

  2. देखो:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. छोर से store:Name="table_name" निकालें।

  4. बदलें store:Schema="whatever"Schema="whatever" को

  5. कि रेखा के नीचे देखो और <DefiningQuery> टैग पाते हैं। इसमें एक बड़ा ओल 'चयन कथन होगा। टैग और इसकी सामग्री हटाएं।
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  6. हम कुछ और ही बदलना होगा:

  7. अब अपनी लाइन कुछ इस तरह दिखना चाहिए। आपकी फ़ाइल के माध्यम से जाओ और लगता है यह:
    <EntityType Name="table_name">

  8. पास में आप शायद कुछ टिप्पणी की पाठ चेतावनी आप देखेंगे कि यह एक प्राथमिक कुंजी पहचान नहीं था कि, तो कुंजी अनुमान लगाया गया है और परिभाषा पढ़ने है केवल टेबल/देखें। आप इसे छोड़ सकते हैं या इसे हटा सकते हैं। मैंने इसे मिटा दिया।

  9. नीचे <Key> टैग है। एंटीटी फ्रेमवर्क डालने/अपडेट/डिलीट करने के लिए उपयोग करने जा रहा है। तो सुनिश्चित करें कि आप इस अधिकार को करते हैं। उस टैग में संपत्ति (या गुण) को एक विशिष्ट पहचान योग्य पंक्ति को इंगित करने की आवश्यकता है। उदाहरण के लिए, मान लीजिए कि मैं अपनी तालिका orders जानता हूं, जबकि इसमें प्राथमिक कुंजी नहीं है, केवल प्रति ग्राहक एक ऑर्डर नंबर होने का आश्वासन दिया जाता है।

    <EntityType Name="table_name"> 
           <Key> 
           <PropertyRef Name="order_numbers" /> 
           <PropertyRef Name="customer_name" /> 
           </Key> 
    

    गंभीरता से, यह गलत नहीं करते:

तो मेरा तरह दिखता है। आइए मान लें कि भले ही डुप्लिकेट न हो, फिर भी दो पंक्तियां मेरे सिस्टम में उसी क्रम संख्या और ग्राहक नाम के साथ मिलती हैं। Whooops! एक कुंजी का उपयोग न करने के लिए मुझे यही मिलता है! इसलिए मैं एक को हटाने के लिए इकाई फ्रेमवर्क का उपयोग करता हूं। क्योंकि मुझे पता है कि डुप्लिकेट आज ही एकमात्र ऑर्डर है, मैं यह करता हूं:

var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today); 
myModel.orders.Remove(duplicateOrder); 

क्या लगता है? मैंने सिर्फ डुप्लिकेट और मूल दोनों को हटा दिया! ऐसा इसलिए है क्योंकि मैंने एंटिटी फ्रेमवर्क को बताया कि order_number/cutomer_name मेरी प्राथमिक कुंजी थी। की तरह कुछ तो जब मैं यह बताया duplicateOrder दूर करने के लिए, क्या यह पृष्ठभूमि में किया था:

DELETE FROM orders 
WHERE order_number = (duplicateOrder's order number) 
AND customer_name = (duplicateOrder's customer name) 

और उस चेतावनी के साथ ... अब आप जाने के लिए अच्छा होना चाहिए!

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