2011-06-11 15 views
19

कहें कि मेरे पास एक कस्टम NSManagedObject Department है और इसमें एक संपत्ति है जो कर्मचारियों के लिए कई रिश्ते का प्रतिनिधित्व करती है i.e. NSSet *employees;कोर डेटा रिलेशनशिप के माध्यम से सभी ऑब्जेक्ट्स को कैसे हटाएं?

किसी दिए गए विभाग के लिए, मैं कर्मचारियों में सभी ऑब्जेक्ट्स को हटाना चाहता हूं। ऐसा करने के लिए अनुशंसित/सर्वोत्तम तरीका क्या है?

तो, परिकल्पित, मेरे कोड इस तरह दिखेगा:

Department.h

@interface Department: NSManagedObject { 
} 
@property (retain) NSString *departmentName; 
@property (retain) NSSet *employees; 
@end 

Department.m

@implementation Department 
@dynamic departmentName; 
@dynamic employees; 

Employee.h

@interface Employee: NSManagedObject { 
} 
@property (retain) NSString *firstName; 
@property (retain) NSString *lastName; 
@property (retain) Department *worksIn; 
@end 

doCoreDataStuff

- (void)doCoreDataStuff:sender { 
    //add a department, give it a couple employees, then try to remove those employees 
    NSEntityDescription *deptEntity = [NSEntityDescription entityForName:@"Department" 
               inManagedObjectContext:self.managedObjectContext]; 
    Department *dept = [Department alloc] initWithEntity:deptEntity 
          insertIntoManagedObjectContext:self.managedObjectContext]; 
    NSError *error; 

    dept.departmentName = @"Accounting"; 
    //save more often than normal to see more easily what causes error 
    if (![self.managedObjectContext save:&error]) NSLog(@"\nError: %@", [error localizedDescription]); 

    NSEntityDescription *empEntity = [NSEntityDescription entityForName:@"Employee" 
               inManagedObjectContext:self.managedObjectContext]; 
    emp.firstName = @"Steve"; 
    emp.lastName = @"Smith"; 
    emp.worksIn = dept; 

    if (![self.managedObjectContext save:&error]) NSLog(@"\nError: %@", [error localizedDescription]); 

    emp = [[Employee alloc] initWithEntity:empEntity 
      insertIntoManagedObjectContext:self.managedObjectContext]; 
    emp.firstName = @"Natasha"; 
    emp.lastName = @"Johnson"; 
    emp.worksIn = dept; 

    if (![self.managedObjectContext save:&error]) NSLog(@"\nError: %@", [error localizedDescription]); 

    //all good so far! now will try to delete all employees for this department 
    dept.employees = [NSSet set]; 
    if (![self.managedObjectContext save:&error]) NSLog(@"\nError: %@", [error localizedDescription]); //"Multiple validation errors occurred." 

    //this also produces the same error 
    [[dept mutableSetValueForKey:@"employees"] removeAllObjects]; 
    if (![self.managedObjectContext save:&error]) NSLog(@"\nError: %@", [error localizedDescription]); //"Multiple validation errors occurred." 

संबंध employees तो मेरा अनुमान है कि विभाग से कर्मचारियों को हटाने का मतलब है कि मैं "अनाथ" कर्मचारियों अर्थात को कायम रखने में कर्मचारियों कोशिश कर रहा हूँ वैकल्पिक नहीं है एक संबंधित विभाग के बिना मॉडल।

तो, मुझे लगता है कि मेरा मूल प्रश्न इस बात का खुलासा किया जाना चाहिए: माता-पिता के साथ गैर-वैकल्पिक संबंध होने पर "माता-पिता" की सभी "बच्चे" वस्तुओं को निकालने का सबसे अच्छा/अनुशंसित तरीका क्या है?

मुझे संदेह है कि उत्तर "एक समय में कर्मचारी वस्तुओं को लूप और हटाएगा"।

अद्यतन

एक जवाब और एप्पल के प्रलेखन के लिए एक लिंक के अनुसार, मैं नष्ट शासन स्थापित करने के लिए करने के लिए "कास्केड" और फिर department.employees = [NSSet set]; की तरह कोड के कार्य करने में सक्षम होना चाहिए। हालांकि, यह मेरे बहुत ही सरल प्रोजेक्ट में काम नहीं करता है जहां मैंने तदनुसार हटाए गए नियम को सेट किया है।

धन्यवाद

+1

मैं आश्चर्य है कि अगर आपको लगता है कि समस्या का समाधान मिल गया है? मुझे एक ही समस्या है .. आपके उदाहरण से चिपकने के लिए मेरे पास एक सिंक्रनाइज़ेशन प्रक्रिया है जहां मैं सभी कर्मचारियों को हटाने की कोशिश कर रहा हूं और बाद में उन्हें स्क्रैच से बना रहा हूं (मेरा सिंक्रनाइज़ेशन बहुत जटिल नहीं है) .. लेकिन वर्तमान में एकमात्र तरीका मुझे लगता है कि काम करने के लिए दोनों पक्षों के लिए 'कई' संबंध जहाज को हटाना था - पुनरावृत्त कर्मचारियों को [प्रबंधित ऑब्जेक्ट कॉन्टेक्स्ट डिलीट ऑब्जेक्ट: कर्मचारी] को कॉल करना और बाद में [[विभाग mutableSetValueForKey: @ "staff"] removeAllObjects]; जो सिर्फ गलत लगता है, लेकिन काम करता है .. – herbert

+0

मुझे काम करने के लिए उपर्युक्त उदाहरण कभी नहीं मिला। अंत में, मैंने कर्मचारियों के माध्यम से पुन: प्रयास किया और उन्हें हटा दिया, जैसा कि नीचे दी गई प्रतिक्रिया में मैंने अभी जवाब – stifin

+3

के रूप में स्वीकार कर लिया है, आप दस्तावेज़ीकरण को गलत समझते हैं। जब आप विभाग ऑब्जेक्ट को हटाते हैं, तो डिलीट नियम कर्मचारियों के सेट में कर्मचारी ऑब्जेक्ट्स पर लागू होगा। रिश्ते को बदलने से कोई ऑब्जेक्ट नहीं हट जाएगा। – Eric

उत्तर

16

आप एक विशिष्ट विभाग के लिए कर्मचारी तत्वों को नष्ट करना चाहते हैं, तो आप चला सकते हैं एक के लिए-इन के लिए

for (Employees * theEmployee in department.employees) { 
    [self.managedObjectContext deleteObject:[self.managedObjectContext objectWithID:theEmployee.objectID]]; 
} 

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

ऊपर पर रूपांतर:

for (Employee *employeeToDelete in department.employees) { 
    [self.managedObjectContext deleteObject:employeeToDelete]; 
} 
+0

जो लूप के सूचक 'theEmployee' को शून्य पर सेट करता है, यह प्रबंधित ऑब्जेक्ट को बिल्कुल प्रभावित नहीं करेगा। –

+0

मेरा बुरा, संपादित;) –

+0

वर्तमान में, यह वह तकनीक है जिसका मैं केवल उपयोग कर रहा हूं क्योंकि मैं कैस्केड को काम नहीं कर सकता ... इसके अलावा मेरा आसान है। मैंने इसे आपके कोड – stifin

14

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

+0

धन्यवाद था तो कोई व्यक्ति तुरंत समस्या का पता लगाएगा - आपका उत्तर इस मामले की जड़ तक पहुंच जाता है और पुष्टि करता है कि मुझे डिलीट नियमों का संदेह कैसे हुआ। मुझे लगता है कि अगर आपने कुछ कोड जोड़ा है तो यह पसंदीदा जवाब बन जाएगा (और निश्चित रूप से चाहिए)। – Benjohn

1

मैं भी नीचे की तरह कुछ था, लेकिन यह काम नहीं किया ...

- (BOOL)deleteCollection:(Collection *)collection 
{ 
// Grab the context 
NSManagedObjectContext *context = [self managedObjectContext]; 
NSError *error = nil; 

[collection removeSounds:collection.sounds]; 
[context deleteObject:collection]; 

// Save everything 
if ([context save:&error]) { 
    return YES; 
} 
return NO; 

}

जाहिर डेटाबेस परत लगता है और तब संग्रह एक बार में नहीं हटा सकते हैं। 'झरना' के लिए रिश्ते पर नष्ट शासन की स्थापना अच्छी तरह से मेरी समस्या हल और मुझे बस का उपयोग करते हैं: तो बस जवाब के रूप में चिह्नित

[context deleteObject:collection]; 

आप को बचाने के लिए कुछ लोगों को समय पढ़ने विस्तृत चाहते हैं।

Fervus जैसा कि ऊपर कहा, इस लिंक पर भी मददगार पेशेवरों के लिए हो सकता है: Propagate deletes immediately in Core Data

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