CoreData NSPredicate与关系

时间:2013-05-24 05:37:31

标签: ios core-data nspredicate

我有以下CoreData对象模型

enter image description here

现在我在制作具有以下条件的谓词时遇到了问题。

获取所有DBOpportunity WHERE

DBOpportunity.stateCode == 1

DBOpportunity.invoiceDate> = GIVEN_DATE

DBOpportunityLines.crmAccept == 1或DBOpportunityLines.crmAccept == 3

我已经尝试了apple的大量示例和编程指南,但无法实现此目的。

3 个答案:

答案 0 :(得分:3)

opportunitylines to-many 关系,因此一个DBOpportunity对象有多个DBOpportunityLines对象。假设最后一个条件

  

DBOpportunityLines.crmAccept == 1或DBOpportunityLines.crmAccept == 3

应该为任何相关对象保留,你需要一个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];

备注:不幸的是,在谓词中使用SUBQUERY的记录很少。 NSExpression类引用中有one example。另请参阅Quick Explanation of SUBQUERY in NSPredicate Expression

答案 1 :(得分:2)

谓词的结构是A && B && (C || D)

设置谓词

NSPredicate *aPredicate = [NSPredicate predicateWithFormat:@"stateCode == %d", value];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"invoiceDate >=  %@", givenDate];

类似于cPredicate和dPredicate。然后首先将c和d与OR结合起来

NSArray *cdPredicateArray = @[cPredicate, dPredicate];
NSPredicate *cdPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:cdPredicateArray];

然后所有这些都与AND

NSArray *allPredicateArray = @[aPredicate, bPredicate, cdPredicate];
NSPredicate *allPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:allPredicateArray];

如果我误解了你的问题而你的结构是A && B && C || D那么你必须首先将A,B和C组合(用AND),然后将该结果与D(用OR)结合起来。

答案 2 :(得分:1)

你也可以获取你的opportunityLines,然后获得这样的父实体:

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"];