create a Compound Predicate in coreData xcode iphone

泄露秘密 提交于 2019-12-08 17:02:06

问题


HI i am working on the core data with 3 entities (Class,Students,ExamRecord) and their relations area as :

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

I created a predicate for fetching list of students for class 5th.

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

with this i am getting all students of class 5th

Now i also want to apply another filter on the Students fetched.

Fetch students whose Exam Record "result" is "Pass".result is an attribute for student in ExamResult entity

How can i make use of Compound predicate in this ?

Please correct me if i am wrong

Any help will be appreciated

Thanks


回答1:


You can use a compound predicate:

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

Or you simply combine the tests with "AND":

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

Note that the argument list of predicateWithFormat is not nil-terminated. The number of arguments is determined by the number of format specifiers in the format string.




回答2:


First, you shouldn't really call the student - class relation studentsToClass. The name of the relation should reflect what type of object is at the other end.

E.g.

In this case the Student relation to Class should be called class because the object there is a single Class entity. The inverse relation should not be called classToStudent it should be called students because the object there is a NSSet of multiple Students.

EDIT

Just to add to this. The name of the relation should explain WHY it is there. We can see that the relation is from class to student but if you call it "classToStudent" it doesn't explain anything. Also, what if you have a second relation from class to student? What do you call that. If you call it attendees or pupils or attendingStudents etc.. it gives the relation meaning.

SOLUTION

In this example I'm going to call them how I would call them and you will see it makes it a bit easier to understand...

Anyway...

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

NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[classPredicate, passPredicate]];



回答3:


First, your quoted predicate is really already wrong. You should reference the managed object, not its property (i.e. not the name of the Class). It should be:

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

Also, you should really choose more readable names for your variables and property. So, not fmt2 but formattingString. Not studentsToClass but form ("class" is a special word in objective-C). You get the idea.

So your desired compound predicate is done like this (short version):

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

The complicated version, if you really need a higher level of abstraction (which I doubt):

classPredicate = [NSPredicate predicateWithFormat:@"class = %@", classObject]; 
resultPredicate = [NSPredicate predicateWithFormat:@"record.result = %@", @"Pass"];
finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:
    @[classPredicate, resultPredicate]];



回答4:


Predicates can also be nested using compounded predicates (For 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])


来源:https://stackoverflow.com/questions/17724068/create-a-compound-predicate-in-coredata-xcode-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!