2010-03-31 11 views
33

मैं इकाई फ्रेमवर्क 4 का उपयोग करता हूं और मेरे पास "कैस्केड डिलीट" सेट के साथ अभिभावक - बाल संबंध है। तो मैं उम्मीद करता हूं कि जब मैं SaveChanges() को कॉल करता हूं तो बच्चे को हटा दिया जाता है जब बच्चे को हटा दिया जाता है।ईएफ 4: संग्रह से बाल वस्तु को हटाने से इसे हटाया नहीं जाता है - क्यों?

System.InvalidOperationException occurred Message=The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

जब मैं स्पष्ट रूप से बच्चों (टिप्पणी की लाइन देखें) हटाते हैं, तो ठीक है:

 cuRepository.Attach(_controlUnit); 
     foreach (var recipe in recipes) { 
      _controlUnit.Recipes.Remove(recipe); 
      //repository.DeleteObject(recipe); 
     } 

इसके बजाय मैं कोई त्रुटि मिलती है। मैं क्या खो रहा हूँ?

+0

मैं आज एक ही समस्या थी देखें और मेरा मानना ​​है कि इस इकाई की रूपरेखा में एक डिजाइन दोष है। SQL सर्वर में तालिकाओं के बीच संबंध "कैस्केड डिलीट अनाथ" बताता है और इसलिए काम करना चाहिए। यह एनएचबेर्नेट में ऐसा काम करता है। सौभाग्य से आप इसे ग्रीममिलर के उत्तर और संबंधित प्रश्नों के बाद काम करने के लिए प्राप्त कर सकते हैं। –

उत्तर

28

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

+2

... तो यदि यह सही जवाब है तो रिश्ते को वास्तव में हटाने के लिए किस कोड का उपयोग किया गया था? –

+2

@ Ek0nomik उन्होंने कहा: repository.DeleteObject (नुस्खा); –

26

http://weblogs.asp.net/zeeshanhirani/archive/2010/07/23/removing-entity-from-a-related-collection.aspx बताते हैं कि वास्तव में क्या हुआ आपको अंदर context.DeleteObject(recipe) जोड़ें।


मान लिया जाये कि आप इस तरह से एक वर्ग डिजाइन कुछ है:

sample class design

इकाई की रूपरेखा के लिए आवश्यक विदेशी कुंजी कॉलम पैदा करते हैं और उन्हें NOT NULL की कमी जोड़ने क्योंकि सभी व्यंजनों हमेशा बिल्कुल साथ संबद्ध किया जाएगा होगा एक नियंत्रण यूनिट।

तो रनटाइम पर आप निम्नलिखित लेआउट के लिए इसी तरह की वस्तुओं होगा:

object diagram at runtime

अब आप अपने कोड खेलने में आता है और पकाने की विधि के बीच संबंध वस्तुओं और उनके ControlUnit नष्ट कर दिया:

objects with deleted relationships

इस समय को बचाने के लिए कोशिश कर रहा है, डेटाबेस विदेशी कुंजी NOT NULL स्तंभ में डाल करने के लिए एक ControlUnit आईडी नहीं है। वर्तमान ऑब्जेक्ट स्टेट उपरोक्त वर्ग आरेख का उल्लंघन करता है और इसे डेटाबेस लेआउट में सहेजा नहीं जा सकता है जो इस धारणा के तहत उत्पन्न किया गया है कि प्रत्येक पकाने की विधि एक ControlUnit से जुड़ी है। यही कारण है कि डेटाबेस परिवर्तनों को सहेजने से इंकार कर देता है और आप अपवाद देखते हैं।

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

"लेकिन मैं रिश्ते पर ON DELETE CASCADE सेट ..."

हाँ, पर है कि केवल वस्तु का विलोपन पर शुरू हो रहा है, रिश्ते का विलोपन पर नहीं।ON DELETE CASCADE सेट के साथ, इस काम करना चाहिए:

:

controlUnitRepository.DeleteObject(_controlUnit); 
// deletes the ControlUnit and all associated Recipe entities 

आप ControlUnit के साथ अपने संबंधों का विलोपन पर पकाने की विधि संस्थाओं का विलोपन को गति प्रदान करना चाहते हैं, अपने रिश्ते एक सरल संघ बल्कि एक रचना नहीं होना चाहिए updated class diagram with composition

ईएफ इस मूल रूप से समर्थन नहीं करता है, लेकिन आप संबंधों की पहचान करके व्यवहार का अनुकरण कर सकते हैं। एक बार एक इकाई एक मूल इकाई के लिए एक पहचान संबंध में है और वह रिश्ते हटा दिया गया है, तो इकाई भी हटा दी गई है। ऐसा लगता है कि यह शुरुआत से आपका इरादा था। रिश्ते की पहचान करने के बारे में अधिक जानकारी के लिए, Implementing identifying relationships with EF4 देखें जहां मैंने ईएफ 4 के साथ संबंधों को पहचानने और अधिक पढ़ने वाली सामग्री से जुड़े हुए हैं।

public static void Delete<T>(this EntityCollection<T> collection, T entityToDelete) where T : EntityObject, IEntityWithRelationships 
{ 
    RelationshipManager relationshipManager = entityToDelete.RelationshipManager; 

    IRelatedEnd relatedEnd = relationshipManager.GetAllRelatedEnds().FirstOrDefault(); 
    if (relatedEnd == null) 
    { 
     throw new Exception("No relationships found for the entity to delete. Entity must have at least one relationship."); 
    } 

    var query = relatedEnd.CreateSourceQuery() as ObjectQuery; 
    if (query == null) 
    { 
     throw new Exception("The entity to delete is detached. Entity must be attached to an ObjectContext."); 
    } 

    query.Context.DeleteObject(entityToDelete); 
    collection.Remove(entityToDelete); 
} 

तो मैं तो Order.Products.Delete(prod) की तरह एक इकाई को हटा दें:

3

मैं बस (http://blogs.msdn.com/b/alexj/archive/2009/06/08/tip-24-how-to-get-the-objectcontext-from-an-entity.aspx से लिया कोड) एक इकाई को हटाने के लिए दाल में एक विधि को जोड़ने के लिए नहीं क्रम में इस एक्सटेंशन का उपयोग।

एक्सटेंशन का उपयोग करने के लिए बाधाएं हैं:
- इकाई के संबंध होना चाहिए;
- ऑब्जेक्ट को ऑब्जेक्ट कॉन्टेक्स्ट से जोड़ा जाना चाहिए।

6

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

संबंधों की पहचान मूल रूप से कहती है कि यदि माता-पिता मौजूद नहीं है तो बच्चे का कोई मतलब नहीं है। इसका मतलब है कि ईएफ जानता है कि रिश्ते को हटा दिए जाने पर बच्चे को हटाना सुरक्षित है।

इस सवाल Identifying Relationship and inserting child entities causes "Cannot insert explicit value for identity column in table" और यह एक Is it possible to remove child from collection and resolve issues on SaveChanges?

+0

यह भी देखें http://stackoverflow.com/questions/3710191/implementing-identifying-relationships-with-ef4 जहां मुझे इस समस्या का सामना करना पड़ा और समझाया कि कैसे संबंधों को पहचानना है। इस ब्लॉग को विस्तार से समझाते हुए एक लिंक भी है। – Chris

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