我有以下 CoreData 对象模型
现在我在制作具有以下条件的谓词时遇到问题。
获取所有那些DBOpportunity
WHERE
DBOpportunity.stateCode == 1
和
DBOpportunity.invoiceDate >= GIVEN_DATE
和
DBOpportunityLines.crmAccept == 1 或 DBOpportunityLines.crmAccept == 3
我已经尝试了很多苹果的示例和编程指南,但无法实现这一点。
我有以下 CoreData 对象模型
现在我在制作具有以下条件的谓词时遇到问题。
获取所有那些DBOpportunity
WHERE
DBOpportunity.stateCode == 1
和
DBOpportunity.invoiceDate >= GIVEN_DATE
和
DBOpportunityLines.crmAccept == 1 或 DBOpportunityLines.crmAccept == 3
我已经尝试了很多苹果的示例和编程指南,但无法实现这一点。
opportunitylines
是一对多关系,因此一个 DBOpportunity 对象有多个 DBOpportunityLines 对象。假设最后一个条件
DBOpportunityLines.crmAccept == 1 或 DBOpportunityLines.crmAccept == 3
应该适用于任何相关对象,您需要一个子查询:
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 类参考中有一个示例。另请参阅NSPredicate Expression 中 SUBQUERY 的快速解释。
你的谓词的结构是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)。
您还可以获取您的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"];