9

嗨,我正在处理具有 3 个实体(班级、学生、考试记录)的核心数据,它们的关系区域为:

Class<------>> Students <------> ExamRecord

我创建了一个谓词来获取第 5 班的学生列表。

NSString * fmt2 = @"studentsToClass.className=%@";
NSPredicate * p2 = [NSPredicate predicateWithFormat:fmt2,@"5th",nil];

有了这个,我得到了第 5 班的所有学生

现在我还想对获取的学生应用另一个过滤器。

获取考试记录“结果”为“通过”的学生。结果是 ExamResult 实体中学生的属性

我如何在此使用复合谓词?

如果我错了请纠正我

任何帮助将不胜感激

谢谢

4

4 回答 4

30

您可以使用复合谓词:

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@", @"5th"];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"studentsToExamRecord.result = %@", @"Pass"];
NSPredicate *p = [NSCompoundPredicate andPredicateWithSubpredicates: @[p1, p2]];

或者您只需将测试与“AND”结合起来:

NSPredicate *p = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@ AND studentsToExamRecord.result = %@",
      @"5th", @"Pass"];

请注意, 的参数列表predicateWithFormat不是-nil终止的。参数的数量由格式字符串中格式说明符的数量决定。

于 2013-07-18T13:03:43.397 回答
2

首先,您不应该真正调用student - class关系studentsToClass。关系的名称应该反映另一端的对象类型。

例如

在这种情况下,应该调用Student关系,因为对象只有一个实体。逆关系不应该被称为它应该被称为因为对象有多个。ClassclassClassclassToStudentstudentsNSSetStudents

编辑

只是为了补充这一点。关系的名称应该解释它为什么存在。我们可以看到这种关系是从班级到学生的,但如果你称它为“classToStudent”,它并不能解释任何事情。另外,如果您在班级与学生之间有第二个关系怎么办?你这叫什么。如果你称它为attendeesor pupilsor attendingStudentsetc.. 它赋予关系意义。

解决方案

在这个例子中,我将用我如何称呼它们来称呼它们,你会发现它更容易理解......

反正...

NSPredicate *classPredicate = [NSPredicate predicateWithFormat:@"class.className = %@", @"5th"];
NSPredicate *passPredicate = [NSPredicate predicateWithFormat:@"result.name = %@", @"Pass"];

NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[classPredicate, passPredicate]];
于 2013-07-18T13:06:21.793 回答
0

首先,您引用的谓词确实已经错了。您应该引用托管对象,而不是其属性(即不是nameClass)。它应该是:

[NSPredicate predicateWithFormat:@"class = %@", classObject]; 

此外,您应该为变量和属性选择更易读的名称。所以,不是fmt2但是formattingString。Not studentsToClassbut form(“class”是objective-C中的一个特殊词)。你明白了。

所以你想要的复合谓词是这样完成的(短版):

[NSPredicate predicateWithFormat:@"class = %@ && record.result = %@",
         classObject, @"Pass"]; 

复杂的版本,如果你真的需要更高级别的抽象(我怀疑):

classPredicate = [NSPredicate predicateWithFormat:@"class = %@", classObject]; 
resultPredicate = [NSPredicate predicateWithFormat:@"record.result = %@", @"Pass"];
finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:
    @[classPredicate, resultPredicate]];
于 2013-07-18T13:04:00.873 回答
0

谓词也可以使用复合谓词嵌套(对于Swift

        let orPredicate = NSCompoundPredicate(type: .or, subpredicates: [date_1KeyPredicate, date_2KeyPredicate])

        let functionKeyPredicate = NSPredicate(format: "function_name = %@", self.title!)

        let andPredicate = NSCompoundPredicate(type: .and, subpredicates: [orPredicate, functionKeyPredicate])
于 2019-02-21T12:55:46.663 回答