Как бы я сформировал предикат результата выборки на основе этой модели данных?
Как бы я вернул все ингредиенты, связанные с рецептами, особенно из рецептов, которые относятся к событиям? А потом заказать их у прохода?
Дальнейшее объяснение:
У пользователя есть "книга рецептов" объектов "Рецепт", которая имеет отношение к ингредиентам. Пользователь будет связывать Рецепт с Событием, когда он планирует подготовить Рецепт. Данные, которые я пытаюсь извлечь, - это список Ингредиентов, которые принадлежат Рецептам, которые принадлежат Событиям, по заказу 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;