2012-11-07 13 views
5

मेरे जीवन के लिए मुझे यह काम करने के लिए प्रतीत नहीं होता है।आप NSFetchRequest setHavingPredicate के लिए पूर्वानुमान कैसे बनाते हैं :?

मान लें कि हमारी इकाई एक स्थिति क्षेत्र और ऑर्डर फ़ील्ड के साथ एक प्रबंधित ऑब्जेक्ट है।

मैं सभी ऑर्डर प्राप्त करने के बारे में कैसे जाउंगा जिसमें एक से अधिक ऑर्डर हैं जो समान हैं?

कृपया मुझे कोई जवाब नहीं दें कि मुझे मुख्य पूर्वानुमान में @ गणना के साथ एक सबक्वायरी करने के लिए कहें, क्योंकि मुझे उस समाधान के बारे में पता है, इस पोस्ट का बिंदु यह समझना है कि मूल डेटा में भविष्यवाणी करने का तरीका कैसे उपयोग किया जाए, शायद किसी भी तरह से एक सबक्वायरी से तेज हो। (जब तक कि आप समझाएं कि मैं एक क्लॉज का उपयोग क्यों नहीं कर सकता)

निम्न कोड ऑर्डर संख्याओं के क्रम में शब्दकोशों की एक श्रृंखला को वापस कर देगा। मैं चाहता हूं कि मेरे अनुरोध को प्रतिबंधित करने के लिए एक क्लॉज जोड़ने में सक्षम होना है, केवल उन ऑर्डर की ऑब्जेक्ट्स का प्रतिनिधित्व करने वाले शब्दकोशों को वापस लौटने में सक्षम होना चाहिए जिनकी संख्या 1 से अधिक है।

यहां तक ​​कि कोड है और मेरे प्रयासों में विधेय:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"OrderedEntry" 
              inManagedObjectContext:context]; 
[fetchRequest setEntity:entity]; 
[fetchRequest setResultType:NSDictionaryResultType]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
       @"(status == %@)",[NSNumber numberWithInt:EntryStatusAlive]]; 


[fetchRequest setPredicate:predicate]; 


NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"order"]; // Does not really matter 
NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:" 
                 arguments: [NSArray arrayWithObject:keyPathExpression]]; 
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
[expressionDescription setName: @"orderCount"]; 
[expressionDescription setExpression: maxExpression]; 
[expressionDescription setExpressionResultType: NSInteger32AttributeType]; 

[fetchRequest setPropertiesToFetch: [NSArray arrayWithObjects:expressionDescription,@"order",nil]]; 


[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:@"order",nil]]; 
//[fetchRequest setHavingPredicate:[NSPredicate predicateWithFormat:@"@count > 1"]]; 
//[fetchRequest setHavingPredicate:[NSComparisonPredicate predicateWithLeftExpression:maxExpression rightExpression:[NSExpression expressionForConstantValue:[NSNumber numberWithInteger:1]] modifier:NSDirectPredicateModifier type:NSGreaterThanPredicateOperatorType options:NSCaseInsensitivePredicateOption]]; 

NSError *error; 

NSArray * array = [context executeFetchRequest:fetchRequest error:&error]; 
+1

आप कभी भी इस पर एक जवाब मिला? मुझे 'setHavingPredicate' के लिए कई बेकार संदर्भ मिले हैं जो इस भविष्यवाणी के प्रारूप के बारे में कोई संकेत नहीं देते हैं। कोई कामकाजी उदाहरण नहीं है, और मैंने जो भी प्रयास नहीं किया है, वह काम कर चुका है ... –

+2

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

उत्तर

0

सबसे पहले, जब भी मैं कुछ आप क्या कर रहे के अनुरूप प्रयास करते हैं, मैं एक त्रुटि है कि आप setPropertiesToFetch: करने के लिए एक से-अनेक संबंध पारित नहीं कर सकते हैं। NSFetchRequest documentation इसका बैक अप लेता है: "संपत्ति विवरण विशेषताओं, एक-रिश्तों या अभिव्यक्तियों का प्रतिनिधित्व कर सकता है।" तो समस्या # 1 है।

समस्या # 2 यह है कि ऐसा लगता है कि आप समूह को कई रिश्ते से नहीं कर सकते हैं (यह दस्तावेज़ीकरण में स्पष्ट नहीं है, लेकिन आपको एक ही त्रुटि मिलती है और यह भी समझ में आता है)।

गुणों से प्राप्त करने के लिए "आदेश" निकालें। एक विशेषता द्वारा समूह। अपने मुख्य पूर्वानुमान को केवल उन विशेषताओं को शामिल करने के लिए संशोधित करें जिन्हें आप समूहबद्ध करते हैं (या बस इसे हटाएं)। अपने भविष्यवाणी में "ऑर्डर" निर्दिष्ट करें।

[fetchRequest setPropertiesToGroupBy: @[ @"???" ]]; 
[fetchRequest setHavingPredicate: [NSPredicate predicateWithFormat: @"[email protected] > 1"]]; 

अब आप अनुरोध काम करेंगे देखेंगे, लेकिन परिणाम शायद तुम क्या नहीं उम्मीद कर रहे थे थे:

- NSArray 
    - NSDictionary { status = @"alive", orderCount = "4" } 
    - NSDictionary { status = @"alive", orderCount = "9" } 
    - NSDictionary { status = @"alive", orderCount = "2" } 
    - etc... 

NSDictionaryResultType वास्तव में आप से उन वस्तुओं की पहचान करने के लिए कुछ भी नहीं देता है - यह सिर्फ आपको मूल्य देता है।

तो आपका अगला कदम उन OrderedEntry ऑब्जेक्ट्स के लिए आईडी वापस प्राप्त करना है। यह चाल include an expression है जो आपको प्रत्येक शब्दकोश में एक कुंजी के रूप में NSManagedObjectID वापस देगी।

मुझे नहीं पता कि यह वास्तव में आपको बेहतर प्रदर्शन प्रदान करेगा (केवल इसे मुख्य भविष्य में और इसमें डालने पर)। मेरे अनुभव में, प्रदर्शन करने में सुधार करने के लिए आप सबसे अच्छी चीजों में से एक है सिंगलटन एनएसपीडिकेटेट्स बनाना और प्रत्येक fetch को सेट करने के लिए प्रतिस्थापन चर का उपयोग करना। भविष्यवाणी पार्सिंग महंगा हो सकता है।

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

+0

मुझे समझ में नहीं आता कि आप क्या कह रहे हैं, setPropertiesToFetch: मैं यहाँ क्या गलत कर रहा हूं? मेरे पास एक विशेषता "ऑर्डर" और अभिव्यक्ति डिस्क्रिप्शन है जो एक अभिव्यक्ति है। समस्या संख्या 2 के लिए – thewormsterror

+0

मेरा ऑर्डर एक विशेषता है, रिश्ते नहीं, इसलिए मैं इसे समझने से समूह कर सकता हूं। – thewormsterror

+0

फिर आप एक विशेषता को गिनने की उम्मीद कैसे करते हैं? ऑर्डर आपके उदाहरण के लिए किसी भी तरह का अर्थ बनाने के लिए बहुत से संबंध होना चाहिए। – karwag

1

मुझे कोई दिलचस्पी किसी के लिए भी इस के साथ जा रहा समाप्त हो गया

-(BOOL)ordersAreSaneOnDay:(NSNumber*)dayNumber forUser:(User*)user inContext:(NSManagedObjectContext*)context { 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"BasicEntry" 
              inManagedObjectContext:context]; 
[fetchRequest setEntity:entity]; 
[fetchRequest setResultType:NSDictionaryResultType]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
       @"(status == %@) && ((type != %@) && (type != %@) && (dayNumber == %@)) && ((user == NIL) || (user == %@))",[NSNumber numberWithInt:EntryStatusAlive],[NSNumber numberWithInt:EntryTypeTask],[NSNumber numberWithInt:EntryTypeCompletedTask],dayNumber,user]; 


[fetchRequest setPredicate:predicate]; 


NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"order"]; // Does not really matter 
NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:" 
                 arguments: [NSArray arrayWithObject:keyPathExpression]]; 
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
[expressionDescription setName: @"orderCount"]; 
[expressionDescription setExpression: maxExpression]; 
[expressionDescription setExpressionResultType: NSInteger32AttributeType]; 

[fetchRequest setPropertiesToFetch: [NSArray arrayWithObjects:expressionDescription,@"order",nil]]; 
[expressionDescription release]; 

[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:@"order",nil]]; 
//[fetchRequest setHavingPredicate:[NSPredicate predicateWithFormat:@"[email protected] > 1"]]; 
//[fetchRequest setHavingPredicate:[NSComparisonPredicate predicateWithLeftExpression:maxExpression rightExpression:[NSExpression expressionForConstantValue:[NSNumber numberWithInteger:1]] modifier:NSDirectPredicateModifier type:NSGreaterThanPredicateOperatorType options:NSCaseInsensitivePredicateOption]]; 

NSError *error; 

NSArray * array = [context executeFetchRequest:fetchRequest error:&error]; 
array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"orderCount > 1"]]; 
//NSLog(@"it worked %@",array); 
[fetchRequest release]; 

if ([array count]) return FALSE; 
return TRUE; 

}

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