2010-01-08 9 views
11

मेरे पास एक एनएसएआरएआर कंट्रोलर है, companiesController शीर्ष स्तर कोर डेटा इकाई, Companies से जुड़ा हुआ है।गहरे संबंधों के लिए कोर डेटा के साथ एनएसपी्रेडिकेट का उपयोग

Company में Department है, और Department में कई Employee हैं; इन्हें 1 से कई रिश्तों, departments और employees द्वारा दर्शाया जाता है।

एक Employee मैंने सोचा कि मैं गतिशील रूप से एक यूआई तथाकथित विधि के अंदर वेतन के आधार पर फ़िल्टर करने के लिए ऐसा कर सकता है की विशेषता salary के आधार पर:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY departments.employees.salary < %@", [NSNumber numberWithInt:23000]]; 
[companiesController setFilterPredicate:predicate]; 

ओह, यह मुझे त्रुटि देता है: -[NSCFSet compare:]: unrecognized selector sent to instance

उत्तर

17

इस मामले में एकाधिक से कई कुंजियों की अनुमति नहीं है।

इसके बजाय, आप निम्न कर सकता है:

  1. विभाग इकाई के लिए एक "फिल्टर" झंडा (बूलियन) विशेषता जोड़कर डेटा मॉडल को संशोधित करें।
  2. सभी विभाग वस्तुओं को लाने के लिए एक विधि बनाएं, अपने पूर्वानुमान के दूसरे भाग के मानदंडों को पूरा करने वाले विभागों के लिए फ़िल्टर ध्वज सेट करें, अन्य विभागों के लिए फ़िल्टर ध्वज को सेट करें, और सहेजें।
  3. कंपनी की भविष्यवाणी में फ़िल्टर ध्वज का उपयोग करें।

कोड परिवर्तन (कदम 3):

//NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY departments.employees.salary < %@", [NSNumber numberWithInt:23000]]; 
    [self setDeptFilter:23000]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY depts.filter == YES"]; 
    [companiesController setFilterPredicate:predicate]; 

और नई विधि (चरण 2):

- (void)setDeptFilter:(NSUInteger)salary { 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Department" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSError *error = nil; 

    // fetch all Department objects 
    NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    [fetchRequest release]; 

    if (error) { 
     NSLog(@"Error fetching Departments %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY emps.salary < %@",[NSNumber numberWithInteger:salary]]; 
    NSArray *filterArray = [array filteredArrayUsingPredicate:predicate]; 

    // set filter flag to YES for the departments that meet the criteria 
    for (Department *dep in filterArray) { 
     dep.filter = [NSNumber numberWithBool:YES]; 
    } 

    NSMutableArray *diffArray = [array mutableCopy]; 
    [diffArray removeObjectsInArray:filterArray]; 

    // set filter flag to NO for the departments that do NOT meet the criteria 
    for (Department *dep in diffArray) { 
     dep.filter = [NSNumber numberWithBool:NO]; 
    } 

    [diffArray release]; 

    // save 
    if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 
+0

धन्यवाद, यह काम करता है। ऐसा लगता है कि कामकाज की तरह लगता है, लेकिन यह सिर्फ कोर डेटा के मुद्दों का अनुमान है। – raheel

+0

मुझे लगता है कि कोर डेटा एनएसपीडिकेट को SQLite कथन में कैसे अनुवाद करता है इसके साथ कुछ करने के लिए यह कुछ है। वाक्यविन्यास संदिग्ध है: क्या आपका मतलब किसी विशेष विभाग में कोई या सभी कर्मचारी है। इसके अलावा, मैं एक एसक्यूएल नौसिखिया हूं, लेकिन मेरा अनुमान यह है कि भले ही आपकी मूल भविष्यवाणी एक सीधा एसक्यूएल कथन में किया जा सके, इसके लिए एक संभावित बड़ी बड़ी आवश्यकता होगी जिसके लिए ऐप्पल एक ही fetch के लिए बहुत मेमोरी या प्रदर्शन गहन विचार कर सकता है। – gerry3

+0

इसके अलावा, मैंने इस पर थोड़ी देर बिताई, इसलिए एक अप-वोट की सराहना की जाएगी :-)। – gerry3

10

तुम भी सबक्वेरी का उपयोग कर ऐसा कर सकता है।

सभी विभाग प्राप्त करें। 'के' संबंध कंपनी के लिए-कई विभागों का उल्टा होता है:

-(void)printDepartmentsWithSalaryHigherThan:(int)salary inContext:(NSManagedObjectContext *)context {  
    NSFetchRequest *request = [[NSFetchRequest alloc ]init]; 
    request.entity = [NSEntityDescription entityForName:@"Department" inManagedObjectContext:context]; 
    request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(employees, $emp, $emp.salary > %@)[email protected] > 0", [NSNumber numberWithInt:salary]]; 

    for(Department *dep in [context executeFetchRequest:request error:nil]){ 
     NSLog(@"Department: %@", dep.depName); 
     NSLog(@"in Company: %@", dep.of.compName); 
    } 
    [request release]; 
} 

या, आप अधिक कंपनियों है और सिर्फ कंपनियों को एक वेतन के साथ एक कर्मचारी है कि चाहते हैं, तो कुछ राशि 'से अधिक'। एक सबक्वायरी

-(void)printCompaniesWithHigherSalaryThan:(int)salary inContext:(NSManagedObjectContext *)context { 
    NSFetchRequest *request = [[NSFetchRequest alloc ]init]; 
    request.entity = [NSEntityDescription entityForName:@"Company" inManagedObjectContext:context]; 
    request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(departments, $dep, SUBQUERY($dep.employees,$emp,$emp.salary > %@)[email protected] > 0)[email protected] > 0", [NSNumber numberWithInt:salary]]; 

    for(Company *c in [context executeFetchRequest:request error:nil]){ 
     NSLog(@"Company: %@", c.compName); 
    } 
    [request release]; 
} 
+0

क्या यह मैक ओएस और आईओएस दोनों के लिए SQLite स्टोर के साथ काम करता है? ऐप्पल प्रलेखन से (आईओएस 5.0 लाइब्रेरी से: कोर डेटा प्रोग्रामिंग गाइड> पर्सिस्टेंट स्टोर फीचर्स> फ़ेचिकेट्स और सॉर्ट डिस्क्रिप्टर प्राप्त करें - मैक ओएस के लिए अलग हो सकते हैं): "उन भविष्यवाणियों पर अतिरिक्त बाधाएं हैं जिनका आप उपयोग कर सकते हैं SQLite स्टोर: आप भविष्य में "मनमानी" SQL क्वेरी का जरूरी अनुवाद नहीं कर सकते हैं।" – Dalmazio

+0

पता नहीं। इसे आज़माएं :) – andershqst

+0

सर्वश्रेष्ठ वास्तविक दुनिया भविष्यवाणी करें सबक्वायर उदाहरण मैं अभी तक –

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