Reputation: 8489
I have following CoreData objects Model
Now I am having issue in making a predicate with following conditions.
Fetch all those DBOpportunity
WHERE
DBOpportunity.stateCode == 1
AND
DBOpportunity.invoiceDate >= GIVEN_DATE
AND
DBOpportunityLines.crmAccept == 1 OR DBOpportunityLines.crmAccept == 3
I have tried lots of examples and programming guide by the apple but can't able to achieve this.
Upvotes: 0
Views: 258
Reputation: 539685
opportunitylines
is a to-many relationship, so there are multiple DBOpportunityLines objects for one DBOpportunity object. Assuming that the last condition
DBOpportunityLines.crmAccept == 1 OR DBOpportunityLines.crmAccept == 3
should hold for any of the related objects, you need a SUBQUERY:
NSDate *givenDate = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"stateCode == 1 AND invoiceDate >= %@ "
"AND SUBQUERY(opportunitylines, $x, $x.crmAccept == 1 OR $x.crmAccept == 3).@count > 0",
givenDate];
Remark: Unfortunately, the usage of SUBQUERY in predicates is poorly documented. There is one example in the NSExpression class reference. See also Quick Explanation of SUBQUERY in NSPredicate Expression.
Upvotes: 3
Reputation: 6190
The structure of your predicate is A && B && (C || D)
Setup your predicates
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:@"stateCode == %d", value];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"invoiceDate >= %@", givenDate];
Similar do the cPredicate and dPredicate. Then first combine c and d with OR
NSArray *cdPredicateArray = @[cPredicate, dPredicate];
NSPredicate *cdPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:cdPredicateArray];
and then all of them with AND
NSArray *allPredicateArray = @[aPredicate, bPredicate, cdPredicate];
NSPredicate *allPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:allPredicateArray];
If I misunderstood your question and your structure is A && B && C || D
Then you have to combine A, B and C first (with AND) and then combine that result with D (with OR).
Upvotes: 2
Reputation: 2295
You could also fetch your opportunityLines
and then get the parent entities like this:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"opportunityLines" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSDate *yourDate = [NSDate date];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(crmAccept==1 OR crmaccept==3) AND opportunity.stateCode==1 AND opportunity.invoiceDate>=%@", yourDate];
[fetchRequest setPredicate:predicate];
NSError *error;
//So here you have your array of opportunitylines
NSArray *opportunityLines = [context executeFetchRequest:fetchRequest error:&error];
//And this is how you get your opportunity objects
NSArray *opportunities = [opportunityLines valueForKeyPath:@"@distinctUnionOfObjects.opportunity"];
Upvotes: 1