2013-07-18 3 views
7

HI Я работаю на основных данных с 3-мя субъектами (класс, студенты, ExamRecord) и их отношения области, как:создать соединение предиката в CoreData Xcode Iphone

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

Я создал предикат для извлечения списка студенты для 5 класса.

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

с этим я получаю все студент класса 5

Теперь я также хочу, чтобы применить еще один фильтр на студентах надуманных.

Fetch студентов, чей экзамен Record «результат» является «Pass» .result является атрибутом для студента в ExamResult субъекта

Как я могу использовать соединение предиката в этом?

Пожалуйста, поправьте меня, если я ошибаюсь

Любая помощь будет оценена

Благодаря

ответ

26

Вы можете использовать соединение предиката:

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

Или вы просто объединить тесты с «И»:

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

Обратите внимание, что список аргументов predicateWithFormat не равен nil. Число аргументов определяется числом спецификаторов формата в строке .

+0

@Fogmeister: Я хотел бы знать. –

+0

@MartinR Спасибо за вашу помощь, но все же я не могу получить результат для Student.My предикат будет: studentsToClass.className == «5-й» и studentsToExamRecord.result == «Пропустить» помощь PLease и исправить меня, где я ошибаюсь – sagar

+0

@sagar: У вас есть ошибка или нет результатов? Возможно, покажите, как определяются сущности и как вы создаете объекты. Получаете ли вы все объекты, если вы опускаете предикат? –

0

Во-первых, ваш цитируемый предикат действительно уже ошибочен. Вы должны ссылаться на управляемый объект, а не на его свойство (т. Е. Не name из Class). Это должно быть:

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

Также вы должны выбрать более читаемые имена для своих переменных и свойств. Итак, не fmt2, но formattingString. Не studentsToClass, но form («класс» - специальное слово в объективе-С). Вы поняли эту идею.

Таким образом, ваше желаемое соединение предиката делается так (короткая версия):

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

Сложный вариант, если вы действительно нужно более высокий уровень абстракции (в чем я сомневаюсь):

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

Как присоединиться к двум субпредациям в один, если они оба являются необязательными, то есть A OR B, а не A AND B. –

+0

Это был бы отдельный вопрос SOF ;-) – Mundi

+0

Да, я нашел, что :) Это делается с использованием orPredicateWithSubpredicates: –

2

Во-первых, вы не должны называть student - class отношением studentsToClass. Имя отношения должно отражать тип объекта на другом конце.

E.g.

В этом случае Student отношение к Class следует назвать class, потому что объект существует единый Class объект. Обратное отношение не следует называть classToStudent, его следует называть students, потому что объект есть NSSet из нескольких Students.

EDIT

Просто добавить к этому. Имя отношения должно объяснять, ПОЧЕМУ оно есть. Мы видим, что отношение от класса к ученику, но если вы называете его «classToStudent», это ничего не объясняет. Кроме того, что, если у вас есть второе отношение от класса к ученику? Как вы это называете? Если вы назовете это attendees или pupils или attendingStudents и т. Д., Это даст значение отношения.

РЕШЕНИЕ

В этом примере я буду называть их, как я бы назвал их, и вы увидите, что делает его немного легче понять ...

Во всяком случае ...

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

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

Спасибо за вашу помощь Но все же я не могу получить студента. Мой предикат становится: studentsToClass.className == "5th" И studentsToExamRecord.result == «Пропустить» PLease помочь и исправить меня, где я ошибаюсь – sagar