在coreData xcode iphone中创build复合谓词
嗨,我正在与3个实体(class级,学生,考试logging)和他们的关系领域核心数据工作:
Class<------>> Students <------> ExamRecord
我创build了一个谓词来获取第五课的学生名单。
NSString * fmt2 = @"studentsToClass.className=%@"; NSPredicate * p2 = [NSPredicate predicateWithFormat:fmt2,@"5th",nil];
有了这个,我得到了第五class的所有学生
现在我也想对学生提交的另一个filter。
获取考试logging“结果”为“通过”的学生.result是ExamResult实体中学生的属性
我怎样才能在这个使用复合谓词?
如果我错了,请纠正我
任何帮助将不胜感激
谢谢
您可以使用复合谓词:
NSPredicate *p1 = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@", @"5th"]; NSPredicate *p2 = [NSPredicate predicateWithFormat:@"studentsToExamRecord.result = %@", @"Pass"]; NSPredicate *p = [NSCompoundPredicate andPredicateWithSubpredicates: @[p1, p2]];
或者您只需将testing与“AND”结合起来即可:
NSPredicate *p = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@ AND studentsToExamRecord.result = %@", @"5th", @"Pass"];
请注意, predicateWithFormat
的参数列表不是终止的。 参数的数量由格式string中的格式说明符的数量决定。
首先,你不应该真的叫student - class
关系studentsToClass
。 关系的名称应该反映在另一端是什么types的对象。
例如
在这种情况下, Student
与Class
关系应该被称为class
因为这个对象有一个Class
实体。 反向关系不应该被称为classToStudent
它应该被称为students
因为对象有一个NSSet
的多个Students
。
编辑
只是为了增加这一点。 关系的名字应该解释为什么在那里。 我们可以看到,这个关系是从一个class级到另一个class级的学生,但是如果你称之为“class级学生”,那么这个关系并不能解释任何事情。 另外,如果你有class级与学生之间的第二个关系呢? 你叫什么? 如果你打电话给attendees
或pupils
或attendingStudents
pupils
等,它给出了关系的含义。
解
在这个例子中,我将打电话给他们,我将如何打电话给他们,你会看到它使得它更容易理解…
无论如何…
NSPredicate *classPredicate = [NSPredicate predicateWithFormat:@"class.className = %@", @"5th"]; NSPredicate *passPredicate = [NSPredicate predicateWithFormat:@"result.name = %@", @"Pass"]; NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[classPredicate, passPredicate]];
首先,你所引用的谓词实际上已经是错误的了。 你应该引用被pipe理的对象,而不是它的属性(即不是Class
的name
)。 它应该是:
[NSPredicate predicateWithFormat:@"class = %@", classObject];
另外,你应该为你的variables和属性select更可读的名字。 所以,不是fmt2
而是formattingString
fmt2
。 不是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]];