在coreData xcode iphone中创建一个复合谓词



HI我正在处理3个实体(class、Students、ExamRecord)的核心数据及其关系区域,如:

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

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

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

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

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

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

在这里我怎样才能使用复合谓语?

如果我错了,请纠正我

如有任何帮助,将不胜感激

感谢

您可以使用复合谓词:

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结尾的。参数的数量由格式中的格式说明符的数量决定一串

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

例如

在这种情况下,StudentClass的关系应该被称为class,因为那里的对象是单个Class实体。逆关系不应被称为classToStudent,而应被称之为students,因为那里的对象是多个StudentsNSSet

编辑

只是为了增加这一点。关系的名称应该解释它为什么存在。我们可以看到这种关系是从班级到学生的,但如果你称之为"班级到学生",它并不能解释任何事情。此外,如果你的班级和学生之间存在第二种关系呢?你怎么称呼它。如果你叫它attendeespupilsattendingStudents等等,它给出了关系的含义。

解决方案

在这个例子中,我将以我对他们的称呼来称呼他们,你会看到这让它更容易理解。。。

不管怎样。。。

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

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

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

此外,您应该为变量和属性选择更可读的名称。所以,不是fmt2,而是formattingString。不是studentsToClass,而是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]];

谓词也可以使用复合谓词嵌套(对于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])

最新更新