2008-11-19 18 views
74

मेरे पास एक मूल वस्तु है जिसमें बाल वस्तुओं के आईएलआईस्ट के साथ कई संबंध हैं। बाल वस्तुओं को हटाने का सबसे अच्छा तरीका क्या है? मैं माता-पिता को हटा नहीं रहा हूं। मेरे मूल वस्तु में बाल वस्तुओं का एक IList शामिल है।NHibernate में बाल ऑब्जेक्ट को कैसे हटाएं?

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 
:

<bag name="Tiers" cascade="all"> 
    <key column="mismatch_id_no" /> 
    <one-to-many class="TGR_BL.PromoTier,TGR_BL"/> 
</bag> 

अगर मैं का उपयोग कर साफ(), तो SaveOrUpdate() फोन संग्रह से सभी वस्तुओं को हटाने की कोशिश करते हैं, मैं इस अपवाद: यहाँ कई रिश्ते के लिए एक के लिए मानचित्रण है

अगर मैं बच्चे को हटाने के लिए वस्तुओं को व्यक्तिगत रूप से तो माता-पिता से उन्हें हटाने की कोशिश, मैं एक अपवाद प्राप्त करें:

deleted object would be re-saved by cascade 

यह मेरा पहला NHibernate में बच्चे वस्तुओं को हटाने के साथ काम कर रहा है। मैं क्या गलत कर रहा हूं?

संपादित करें: बस स्पष्ट करने के लिए - मैं मूल वस्तु को हटाने की कोशिश नहीं कर रहा हूं, केवल बाल वस्तुओं को हटा रहा हूं। मेरे माता-पिता पर कई लोगों के साथ संबंध स्थापित हैं। क्या मुझे बच्चे ऑब्जेक्ट मैपिंग पर कई से एक रिश्ते बनाने की भी आवश्यकता है?

उत्तर

130

आपको पहली त्रुटि मिल रही है क्योंकि, जब आप संग्रह से आइटम हटाते हैं, तो NHibernate का ऑपरेशन का डिफ़ॉल्ट तरीका बस एसोसिएशन को तोड़ना है। डेटाबेस में, NHibernate बच्चे की पंक्ति पर विदेशी कुंजी कॉलम को शून्य पर सेट करने का प्रयास करता है। चूंकि आप उस कॉलम में नल की अनुमति नहीं देते हैं, इसलिए SQL सर्वर त्रुटि उठाता है। संग्रह को साफ़ करने से बच्चे की वस्तु को जरूरी नहीं हटाया जाएगा, लेकिन ऐसा करने का एक तरीका है कैस्केड = ऑल-डिलीट-अनाथ सेट करना। यह NHibernate को सूचित करता है कि इसे विदेशी कुंजी कॉलम सेट करने की बजाय नई अनाथ पंक्तियों को हटा देना चाहिए।

आपको दूसरी त्रुटि मिल रही है क्योंकि जब आप SaveOrUpdate NHibernate को कॉल करते हैं तो पहले सभी बच्चे ऑब्जेक्ट को हटा दें। फिर, क्योंकि न तो रिश्ते को विपरीत के रूप में चिह्नित किया जाता है, NHHernate भी आपके बच्चे की तालिका में विदेशी कुंजी कॉलम को शून्य पर सेट करने का प्रयास करता है। चूंकि पंक्तियां पहले से ही हटा दी गई हैं, इसलिए आपको दूसरी त्रुटि मिलती है। इसे ठीक करने के लिए आपको अपने रिश्ते के एक तरफ व्यस्त = सत्य सेट करना होगा। यह आमतौर पर एक (प्राथमिक कुंजी या अभिभावक) पक्ष पर किया जाता है। यदि आप ऐसा नहीं करते हैं, तो NHibernate रिश्ते के प्रत्येक पक्ष के लिए उपयुक्त अपडेट करेगा। दुर्भाग्य से, दो अपडेट चलाना उचित बात नहीं है।

आपको हमेशा अपने रिश्ते के एक तरफ विपरीत पक्ष के रूप में चिह्नित करना चाहिए। आप कैसे कोड करते हैं, इस पर निर्भर करते हुए, आपको कैस्केडिंग का उपयोग करने की आवश्यकता हो सकती है या नहीं। यदि आप एक शॉट डिलीट का लाभ लेना चाहते हैं क्योंकि आप साफ़() का उपयोग करके करने की कोशिश कर रहे हैं, तो आपको अपने कैस्केड को परिभाषित करने की आवश्यकता है।

+0

बस स्पष्ट करने के लिए - मुझे अभी केवल माता-पिता ऑब्जेक्ट पर रिश्ते को परिभाषित किया गया है। मैंने उस ऑब्जेक्ट पर कैस्केड को "ऑल" और "ऑल-डिलीट-अनाथ" दोनों बार एक ही परिणाम के साथ सेट करने का प्रयास किया है। तुम्हारा मतलब है कि मुझे बच्चे के ऑब्जेक्ट पर कई से एक रिश्ते को परिभाषित करने की ज़रूरत है? –

+0

और इस मामले में उलटा = "सत्य" माता-पिता या बच्चे की वस्तु पर है? –

+2

यह उस वर्ग से संबंधित है जिसमें विदेशी कुंजी नहीं है ... आमतौर पर माता-पिता। – pmlarocque

-3

समस्या उत्पन्न करने वाले कॉलम पर आपके मानचित्रण में नॉट-नल = सत्य सेट करें। मुझे सटीक वाक्यविन्यास के बारे में निश्चित नहीं है हालांकि (क्षमा करें)।

+0

ठीक है, मैंने कॉलम को ऑब्जेक्ट के मैपिंग पर नोट-नल = "सत्य" पर सेट किया है। इसलिए, मैं बाल ऑब्जेक्ट्स के आईएलआईस्ट पर स्पष्ट() विधि को कॉल करता हूं, फिर SaveOrUpdate() को आज़माएं। मैं अभी भी "कॉलम में मूल्य न्यूल को सम्मिलित नहीं कर सकता" त्रुटि प्राप्त कर रहा हूं। क्या मैं कुछ और गलत कर रहा हूँ? –

+0

कौन सा कॉलम फेंक दिया जा रहा है? आप अपने मॉडल में बच्चों को वास्तव में कैसे हटा रहे हैं? –

+0

मैं अपने मूल ऑब्जेक्ट में Ilist बाल ऑब्जेक्ट पर स्पष्ट() विधि को कॉल कर रहा हूं। फिर मैं माता-पिता पर SaveOrUpdate() को कॉल कर रहा हूं। –

0

"सभी" से "सब-डिलीट-अनाथ" में कैस्केड विशेषता मान बदलें।

+0

कोशिश की। मुझे अभी भी एक ही अपवाद मिल रहा है। –

+16

ऑल-डिलीट-अनाथ बच्चों को हटाते समय बच्चों को हटा देता है। इस लड़के की तरह बच्चों को हटाने के साथ इसका कोई संबंध नहीं है। –

2

saveOrUpdate() के बजाय विलय() का उपयोग करने का प्रयास करें। साथ ही, सुनिश्चित करें कि आपका कैस्केड ऑल-डिलीट-अनाथ पर सेट है और यह कि आपके माता-पिता का रिश्ते अचूक है (माता-पिता पर उलटा = सत्य है और फिर उस बच्चे में एक फ़ील्ड है जो माता-पिता के साथ गैर-सत्य = सत्य है) ।

2

हमारे उदाहरण में हमारे पास कई उत्पादों के साथ श्रेणियां हैं जहां कोई उत्पाद शून्य नहीं है।

आप उत्पाद को हटाकर और फ्लश से पहले माता-पिता के संग्रह से इसे हटाकर समस्या के आसपास काम कर सकते हैं लेकिन हम अभी भी इसके लिए बेहतर समाधान ढूंढ रहे हैं।

product = pRepo.GetByID(newProduct.ProductID); 
product.Category.Products.Remove(product); 
pRepo.Delete(product); 

आशा है कि यह वैसे भी मदद करता है

+0

हालांकि इसके लिए एक और भंडार की आवश्यकता है। – UpTheCreek

3

चक के जवाब के अनुसार, मैं उलटा = माता-पिता की ओर मानचित्रण में सच जोड़कर मेरी समस्या हल हो गई है:

[HasMany(typeof(MessageSentTo), Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true)] 
public IList<MessageSentTo> MessageSendTos 
{ 
    get { return m_MessageSendTo; } 
    set { m_MessageSendTo = value; } 
} 
:

संदेश कई MessageSentTo है

मैं कैसल एक्टिव रिकार्ड का उपयोग कर रहा हूं। चक धन्यवाद

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