Как бы я сформировал предикат результата выборки на основе этой модели данных?

Как бы я вернул все ингредиенты, связанные с рецептами, особенно из рецептов, которые относятся к событиям? А потом заказать их у прохода?

Дальнейшее объяснение:

У пользователя есть "книга рецептов" объектов "Рецепт", которая имеет отношение к ингредиентам. Пользователь будет связывать Рецепт с Событием, когда он планирует подготовить Рецепт. Данные, которые я пытаюсь извлечь, - это список Ингредиентов, которые принадлежат Рецептам, которые принадлежат Событиям, по заказу Aisle. В основном "список покупок".

Дальнейшее объяснение того, что является объектом Event: События допускают дублирование рецептов. Скажем, у меня будет жареное яйцо (ингредиент = "1 свежее яйцо") в течение 3 дней подряд (3 отдельных события), я хочу, чтобы список покупок содержал "1 свежее яйцо" три раза - по одному экземпляру для каждого события.

Вот мой запрос на выборку, который не возвращает никаких результатов - я предполагаю, что суть проблемы заключается в предикате:

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Ingredient"    inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];

// get ingredients of recipes that belong to events
[request setPredicate:[NSPredicate predicateWithFormat:@"Ingredient.recipe == Event.recipe"]];

// sort by "aisle"
NSSortDescriptor *sortDescriptorCategory = [NSSortDescriptor sortDescriptorWithKey:@"aisle" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:sortDescriptorCategory, nil];

// create nsfrc with "aisle" as sectionNameKeyPath
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"aisle" cacheName:@"MyFRCCache"];
frc.delegate = self;
NSError *error = nil;
if (![frc performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
self.fetchedResultsController = frc;

Благодаря вопросу Мартина Р, я еще больше уточнил проблему. Вот некоторые примеры данных и желаемый результат:

Рецепт

Z_PK = 1, ZTITLE = "Овсянка"
Z_PK = 2, ZTITLE = "Сэндвич с арахисовым маслом и желе"
Z_PK = 3, ZTITLE = "Сэндвич с сыром гриль"
Z_PK = 4, ZTITLE = "Говядина тушеная"
Z_PK = 5, ZTITLE = "Гамбургер"
... Плюс больше рецептов, которые не будут включены в результаты поиска...

Событие

Z_PK = 1, ZTITLE = "Завтрак 1", ZRECIPE = 1
Z_PK = 2, ZTITLE = "Обед 1", ZRECIPE = 2
Z_PK = 3, ZTITLE = "Ужин", ZRECIPE = 4
Z_PK = 4, ZTITLE = "Завтрак 2", ZRECIPE = 1 // Обратите внимание на повторение рецепта
Z_PK = 5, ZTITLE = "Обед 2", ZRECIPE = 3
Z_PK = 6, ZTITLE = "Ужин 2", ZRECIPE = 5

Ингредиент

Z_PK = 1, ZTITLE = "1 чашка овсянки", ZRECIPE = 1, ZAISLE = 4
Z_PK = 2, ZTITLE = "2 чашки молока", ZRECIPE = 1, ZAISLE = 2
Z_PK = 3, ZTITLE = "2 куска белого хлеба", ZRECIPE = 2, ZAISLE = 5
Z_PK = 4, ZTITLE = "1 столовая ложка желе", ZRECIPE = 2, ZAISLE = 4
Z_PK = 5, ZTITLE = "1 столовая ложка арахисового масла", ZRECIPE = 2, ZAISLE = 4
Z_PK = 6, ZTITLE = "2 шт ржаного хлеба", ZRECIPE = 3, ZAISLE = 5
Z_PK = 7, ZTITLE = "1 ломтик сыра", ZRECIPE = 3, ZAISLE = 2
Z_PK = 8, ZTITLE = "1 фунт. Жареный цыпленок", ZRECIPE = 4, ZAISLE = 3
Z_PK = 9, ZTITLE = "2 моркови", ZRECIPE = 4, ZAISLE = 1
Z_PK = 10, ZTITLE = "2 картофеля", ZRECIPE = 4, ZAISLE = 1
Z_PK = 11, ZTITLE = "1 булочка с гамбургером", ZRECIPE = 5, ZAISLE = 5
Z_PK = 12, ZTITLE = "1/4 фунт гамбургер", ZRECIPE = 5, ZAISLE = 3

придел

Z_PK = 1, ZTITLE = "Производить", ZDISPLAYORDER = 1
Z_PK = 2, ZTITLE = "Молочные продукты", ZDISPLAYORDER = 2
Z_PK = 3, ZTITLE = "Мясо", ZDISPLAYORDER = 3
Z_PK = 4, ZTITLE = "Сухие и консервированные продукты", ZDISPLAYORDER = 4
Z_PK = 5, ZTITLE = "Пекарня", ZDISPLAYORDER = 5

Желаемый результат (отсортировано по Aisle ZDISPLAYORDER, полужирные элементы - заголовки разделов)

Производить
-2 моркови
-2 картошки
Молочные продукты
-2 стакана молока
-2 стакана молока // второй предмет, потому что есть два экземпляра рецепта
-1 ломтик сыра
Колбасные изделия
-1 кг жареный цыпленок
Гамбургер -1/4 фунта
Сухие и консервированные продукты
-1 чашка овсянки
-1 чашка овсянки // второй предмет, потому что есть два экземпляра рецепта
-1 ст. Л. желе
-1 столовая ложка арахисового масла
пекарня
-2 штуки белого хлеба
-2 штуки ржаного хлеба
-1 булочка с гамбургером

2 ответа

Я думаю, что вы хотите предикат:

recipe.events.@count > 0

Это поможет вам Ingredients используется в любом Recipes которые для любого Event,

Или если вы ищете Ingredients используется в любом Recipe для конкретного Event, это было бы:

[NSPredicate predicateWithFormat:@"ANY recipe.events = %@", specificEvent]

Ваш дескриптор рода, вероятно, будет aisle.displayOrder, не просто aisle,

Запрос выборки не может (насколько мне известно) возвращать дубликаты записей одного и того же управляемого объекта. Итак, самое близкое решение, которое у меня есть, заключается в следующем.

Соберите все ингредиенты и разложите их по разделам в соответствии с aisle.displayOrder, В каждом разделе сортируйте ингредиенты по их собственному порядку отображения:

NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"aisle.displayOrder" ascending:YES];
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"displayOrder" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:sort1, sort2, nil];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
    managedObjectContext:self.managedObjectContext
    sectionNameKeyPath:@"aisle.displayOrder"
    cacheName:@"fetchControllerCache"];

Для каждого ингредиента вы можете подсчитать количество событий (и отобразить это в своей таблице):

int numberOfEvents = theIngredient.recipe.events.count;
Другие вопросы по тегам