21

हम विदेशी कुंजी संबंधों के साथ पहले इकाई फ्रेमवर्क कोड का उपयोग कर रहे हैं। हम अपने आवेदन में एक संस्था आईसीओलेक्शन से वस्तुओं को हटाने के तरीकों की जांच कर रहे हैं।क्या बचपन से बच्चे को हटाने और SaveChanges पर समस्याओं को हल करना संभव है?

जब हमारे पास बाल संबंधों के साथ एक इकाई होती है तो हम ऐड विधि का उपयोग करके ऑब्जेक्ट को सीधे अपने आईसीलेक्शन में जोड़ सकते हैं। अब जब आप को दूर का उपयोग आप त्रुटि

System.InvalidOperationException संदेश हुआ मिलता है = आपरेशन विफल रहा है: क्योंकि एक या के और अधिक विदेशी कुंजी गुण गैर-व्यर्थ है रिश्ता बदला नहीं जा सका। जब संबंध में कोई परिवर्तन किया जाता है, तो संबंधित विदेशी-कुंजी संपत्ति शून्य मान पर सेट होती है। यदि विदेशी कुंजी शून्य मानों का समर्थन नहीं करती है, तो एक नया रिश्ते परिभाषित किया जाना चाहिए, विदेशी-कुंजी प्रॉपर्टी को गैर-शून्य मान असाइन किया जाना चाहिए, या असंबंधित ऑब्जेक्ट को हटा दिया जाना चाहिए।

मुझे समझ में आता है क्योंकि संग्रह पर निकालें केवल विदेशी कुंजी को हटाकर रिश्ते को हटा देता है। हम अपनी इकाई में हमारे व्यापार तर्क लिखना चाहते थे और हटाने की अनुमति देते थे।

तो ऑर्डर रिपॉजिटरी से रूट इकाई को बाहर निकालें, उदाहरण के लिए इकाई की कुछ विशिष्ट विधि उदा। Order.AddOrderline(Orderline orderline) यह आदेश virtual ICollection<OrderLine> OrderLines

लेकिन हम नहीं है क्योंकि बस ICollection से निकालने बचत परिवर्तन पर एक त्रुटि का कारण बनता है Order.CancelOrderline(int orderLineId) की तरह कोड लिख सकते हैं करने के लिए एक ऑर्डर लाइन कहते हैं।

ऑब्जेक्ट संग्रहों में केवल छेड़छाड़ करके इसे प्राप्त करने के लिए वैसे भी ऐसा प्रतीत नहीं होता है। जाहिर है हम सीधे संदर्भ से हटा सकते हैं। हालांकि मैं इसे इकाई का हिस्सा बनाना चाहता हूं। क्या हम एंटीटी फ्रेमवर्क की सेवचेंज घटना पर कोई विदेशी कुंजी नहीं रख सकते हैं? स्पष्ट रूप से ईएफ को बताने की जरूरत है कि अगर उनके पास शून्य विदेशी कुंजी है तो कौन सी संस्थाओं को हटाया जा सकता है।

वर्तमान में हम एक भंडार पैटर्न का उपयोग कर रहे हैं ताकि नियंत्रक के पास संदर्भ तक पहुंच न हो। मैं ऑर्डर रिपॉजिटरी पर ऑर्डरलाइन रिपोजिटरी या ऑर्डरलाइन विधि को हटा सकता हूं। हालांकि बस सोच रहा है कि दृढ़ता तंत्र के संदर्भ के बिना इकाई पर कोड लिखना संभव था।

विचार? क्या हम इस सब गलत के बारे में जा रहे हैं? क्या अन्य ओआरएम आपको बाल संग्रह से हटने की अनुमति देते हैं?

उत्तर

38

मुझे नहीं पता कि निम्नलिखित आपके लिए एक समाधान है, लेकिन इकाई फ्रेमवर्क Identifying Relationships का समर्थन करता है। इस तरह के रिश्ते में माता-पिता (मूल) को बाल इकाई (निर्भर) की विदेशी कुंजी बाल इकाई की (समग्र) प्राथमिक कुंजी का हिस्सा होना चाहिए।DbContext डेटा एनोटेशन के साथ - - उदाहरण के लिए अपने मॉडल वर्गों इस तरह दिखना चाहिए:

public class Order 
{ 
    [Key] 
    public int OrderId { get; set; } 

    public ICollection<OrderLine> OrderLines { get; set; } 
} 

public class OrderLine 
{ 
    [Key, ForeignKey("Order"), Column(Order = 1)] 
    public int OrderId { get; set; } 

    [Key, Column(Order = 2)] 
    public int OrderLineId { get; set; } 

    public Order Order { get; set; } 
} 

आप OrderLineId एक स्वत: जनरेट की पहचान अगर आप चाहते हैं कर सकते हैं। महत्वपूर्ण यह है कि एफके से Order पीके का हिस्सा है।

उदाहरण के लिए इस तरह का कोड ...

using (var ctx = new MyContext()) 
{ 
    var order = ctx.Orders.Include("OrderLines").Single(o => o.OrderId == 1); 
    var orderLineToDelete = order.OrderLines 
     .FirstOrDefault(ol => ol.OrderLineId == 5); 
    if (orderLineToDelete != null) 
     order.OrderLines.Remove(orderLineToDelete); 

    ctx.SaveChanges(); 
} 

... वास्तव में orderLineToDelete डेटाबेस से हटाना होगा।

अधिक जानकारी here अनुभाग में पहचान और पहचानने वाले संबंधों के लिए विचार "।

+0

आह इसलिए यदि मैं बाल संस्थाओं पर एक समग्र कुंजी बना देता हूं तो ईएफ मेरे लिए इस से निपटेंगे। अब यह काफी आकर्षक लगता है। – GraemeMiller

+6

यह बहुत अच्छा था लेकिन मुझे [कुंजी, कॉलम (ऑर्डर = 0), डाटाबेस जेनरेटेड (डाटाबेस जेनरेटेडऑप्शन.इडेन्टिटी) जोड़ने की जरूरत है] सार्वजनिक int ऑर्डरलाइन Id {get; सेट; } पहचान सम्मिलन के बारे में शिकायत नहीं करने के लिए। – GraemeMiller

+0

@GraemeMiller: यही मेरा मतलब है "* यदि आप चाहते हैं तो आप ऑर्डरलाइन को एक स्वत: उत्पन्न पहचान बना सकते हैं * :) :) मैं यह उल्लेख करना भूल गया कि आपको * मॉडल * (डेटाबेस जेनरेटेडऑप्शन के साथ) * और * में ऐसा करने की ज़रूरत है डेटाबेस*। – Slauma

2

जैसा कि आप खोज रहे हैं, यदि आप केवल संग्रह से एक इकाई को हटाते हैं तो एंटीटी ऑब्जेक्ट संदर्भ से जुड़ा हुआ है और आपको SaveChanges() पर कॉल करने पर त्रुटि मिलती है; मैंने डोमेन घटनाओं का उपयोग एक रिपोजिटरी के माध्यम से ऑब्जेक्ट संदर्भ से इकाई को हटाने का एक साफ तरीका सक्षम करने के लिए किया है।

मैंने अपने उत्तर to this question में इस दृष्टिकोण का विस्तृत विवरण दिया है।

+0

यह वास्तव में एक दिलचस्प दृष्टिकोण की तरह दिखता है। क्या यह कमांड पैटर्न के समान है? मुझे मॉडलिंग डोमेन घटनाओं की अवधारणा पसंद है। मुझे वास्तव में मेरी नीली किताब पढ़ने को पूरा करने की ज़रूरत है। – GraemeMiller

+1

हम्म ... वास्तव में कमांड नहीं, मुझे नहीं लगता - डोमेन घटनाएं व्यवहार रहित वस्तुएं हैं जो संकेत देती हैं कि किसी भी वस्तु को कुछ संभालता है जो उन्हें संभालता है। मुझे लगता है कि मैंने पहली बार [मार्टिन फाउलर] (http://martinfowler.com/eaaDev/DomainEvent.html) से उनके बारे में पढ़ा है, लेकिन [यह आलेख] (http://www.udidahan.com/2009/06/14/ डोमेन-इवेंट्स-मोक्ष) वह था जिसने वास्तव में मुझे यह समझने में मदद की कि वे कितने शक्तिशाली हैं :) –

+0

ग्रेट जो समझ में आता है क्योंकि उनके पास कोई पेलोड नहीं है जैसा कि आप कहते हैं। उस पर पढ़ा जाएगा। अतिरिक्त संदर्भों की सराहना करें। – GraemeMiller

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

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