1

Я столкнулся с проблемой одного из моих проектов, я потратил дюжину часов, чтобы найти решение, я добился определенного прогресса, но до сих пор не получаю того, чего бы я хотел достичь в идеале. Сейчас я все еще нахожу решения, хотя я бы очень признателен, если кто-нибудь может поделиться идеей о конструктивных решениях.Как добавить целевой объект NSManagedObject к другому с обратным отношением Core Data ко многим ко многим, не дублируя целевой NSManagedObject?

Выпуск:

  • Как добавить целевой NSManagedObject из основного списка в качестве одного объекта ссылок в другой NSManagedObject с обратным многие-ко-многим между каждым NSManagedObject без создания дублируйте цель NSManagedObject в главном списке.

Примечание:

  • Следующий пример использовал аналогию с полной модели данных графиков на мой реальный проект. Аналогия - это то, что я могу лучше всего описать проблемой. У меня есть, в то время как объекты в аналогии не полностью разделяют те же имя объектов в реальном проекте.

Что я сейчас:

  • Мастер список ингредиентов объектов, которые являются уникальными среди каждого
    другой.

  • Список объектов рецепта, каждый из которых хотел бы иметь различные объекты ингредиентов для определения объекта рецепта.

Что я хочу достичь:

  • объекты ингредиент может быть вставлен в несколько раз в один объект рецепт с каждой вставки в качестве уникального графа вместо того, чтобы тот же компонент рассматривается как один счет.

  • Я не хочу, чтобы дублировать каждый объект ингредиента внутри от основного списка, чтобы иметь возможность добавлять несколько компонентов объектов для каждого объекта рецепта или пересекать несколько объектов рецепта.

Что я пробовал:

  • Использование основных данных для управления ингредиент и рецепт, как 2 NSManagedObjects.

  • создал отношения атрибутов, называемые «allHostRecipes» на ингредиент управляемого объекта и установить его в качестве «ко-многим» отношения к рецепту управляемого объекту

  • создал отношения атрибуты называются «allUsedIngredients» на объект, управляемый рецептом, и установить его как отношение «to-Many» к объекту, управляемому ингредиентом.

  • Эти две связи заданы как «обратные».
  • У меня был рецепт Описание Просмотр с таблицей, в которой перечислены все ингредиенты, которые включены и будут включены внутрь рецепта.
  • Я создал другую таблицу выбора ингредиентов, которая может быть запущена в представлении описания рецепта, чтобы выбрать каждый ингредиент, который будет добавлен в рецепт.
  • Каждый раз, когда ингредиент выбирается в виде таблицы выбора ингредиентов, я вызываю objectAtIndexPath (_ :) в NSFetchedResultsController, который предназначен для ингредиентов Table View из основного списка ингредиентов, чтобы найти выбранные объекты ингредиентов в ManagedObjectContext.
  • Затем я передал выбранный ингредиент управляемый объект (SelectedIngredientManagedObject) обратно Рецепт Описание Вид и называется mutableSetValueForKey («allUsedIngredients»). AddObject (SelectedIngredientManagedObject) на NSFetchedResultsController, который предназначен для извлечения ингредиентов, которые содержатся внутри объекта рецепта.

  • «NSFetchedResultsController, который предназначен для ингредиентов Таблица Вид из основного списка ингредиентов» и «NSFetchedResultsController, который предназначен для получения ингредиентов, содержащихся внутри объекта рецепта», являются отдельными переменными экземпляра в «Таблица видов рецепта Описание View »И« Просмотр таблицы ингредиентов ». Но они ссылались на тот же ManagedObjectContext.

То, что я получил в настоящее время:

  • Выбранный компонент управляемый объект может быть добавлен в рецепте.
  • Но, если я выбрал один и тот же ингредиент несколько раз, он получает только один раз в таблице Виды представления рецепта Описание вместо того, чтобы показывать несколько отсчетов по каждой вставке, что НЕ является тем, чего я хочу достичь, как описано выше.

Мой вопрос:

  • Что я должен делать и настраивать для достижения функциональности, что я имел описать выше?

Что я думаю, что направления, чтобы решить вопрос:

  • Какие другие вещи, которые я должен делать при определении «многие-ко-многим» отношения в базовой модели данных?
  • Означает ли факт, что ссылка «to-Many» использует NSSet, вызывает проблему с подсчетом?
  • Нужно ли создавать несколько ManagedObjectContext для достижения желаемых функциональных возможностей?
  • Должен ли я клонировать выбранный ингредиент, управляемый объект, как объект, управляемый новым ингредиентом? Что я пробовал, и он добавит дублированный ингредиент в основной список ингредиентов. Это тоже НЕ то, что я хочу. Если мне нужно клонировать его, как я могу это исправить?

Я очень ценю ваше время, чтобы посмотреть его, я с нетерпением жду ваших взглядов. Большое спасибо.

С уважением,

Knight

ответ

2

Вам нужно немного переделать данные: Удалите многие-многие отношения с Recipe к Ingredient, и заменить его с промежуточным объектом (нахождение хорошее имя трудно, давайте RecipeIngredientDetails).

Создать один-многим из Recipe к RecipeIngredientDetails, скажем allUsedIngredientDetails, с обратной (к-одному) recipe.

Аналогично создать один-многим из Ingredient к RecipeIngredientDetails, скажем allHostRecipeDetails с обратной (к-одному) ingredient.

Это относится к проблеме с прямым отношением много-много, где каждый Recipe может быть связан с каждым Ingredient только один раз. (Вы правы, это отчасти связано с тем, что отношения моделируются как Sets, которые не могут иметь повторяющихся членов). У вас есть два варианта: вы можете просто добавить несколько объектов RecipeIngredientDetails, каждый из которых связан с теми же Recipe и Ingredient парой. Каждый такой объект может представлять собой стандартное базовое количество ингредиента. Обратите внимание, что у вас не может быть только один объект для каждой пары Recipe/Ingredient, и попробуйте добавить этот объект к тому же Recipe несколько раз: данный Recipe и данный объект RecipeIngredientDetails могут быть связаны не более одного раза.

Но, возможно, было бы лучше добавить атрибут к RecipeIngredientDetails, скажем quantity. Затем вам нужен только один такой объект для каждой пары Recipe/Ingredient и может обновить атрибут quantity, чтобы отразить количество ингредиента, подходящего для этого рецепта.

Этот подход упоминается в разделе Руководство по программированию на CoreData Modeling a Relationship Based on Its Semantics:

Для такого рода отношений, использовать промежуточный (Join) юридическое лицо. Преимущество промежуточной сущности заключается в том, что вы также можете использовать ее для добавления дополнительной информации в отношения.

Это эквивалентно добавлению таблицы соединений с внешними ключами и дополнительными столбцами в базу данных SQL. Я не знаю более простого способа достижения ваших целей в CoreData - нет никакого способа напрямую добавлять атрибуты к отношениям.

Что касается вопроса о заказе, который вы упомянули в комментариях, вы добавили в атрибут атрибут Double type для отслеживания заказа. Если у вас есть только два объекта и много-много отношений, и вы добавляете атрибут order к Ingredient, то (например), если «Мука» является первым ингредиентом для «Хлеба», это должен быть первый элемент для каждый другой рецепт, в котором он используется.В описываемом подходе вы добавляете атрибут к промежуточному объекту, RecipeIngredientDetails: индекс (как и для количества) зависит от и рецепт и его состав.

Для индексов есть, однако, еще один вариант, который я должен упомянуть: вы могли бы (в редакторе модели данных) определить отношение от Рецепта к RecipeIngredientDetails как приказал. Получающееся свойство будет упорядоченным набором (чтобы вы могли вставлять, удалять или перемещать элементы для достижения правильного порядка).

+0

Спасибо, pbasdf. Я думаю, что вы дали мне одно замечательное решение для решения проблемы, а подход, о котором вы говорили выше, похож на добавление отдельной таблицы в реляционную базу данных, где добавленная таблица будет содержать набор пар ключей, которые могут быть первичными или внешние ключи? Хотя Core Data имеет более простой способ справиться с этим, а не создавать отдельную таблицу? например, манипулирование некоторыми свойствами в отношениях? – MKD

+0

Кроме того, для первого варианта, о котором вы упоминали, мне нужно несколько копий «RecipeIngredientDetails» и добавить их в любой родственный рецепт и ингредиенты? Или просто создать один экземпляр этого и позволить кому-либо ссылаться на это? Для второго варианта, интересно, что, если я могу сделать это соответствовать моей цели, которая является добавленным ингредиентом, нужно заказать в рецепте. Обратите внимание, что я решил проблему с индексом в модели Core Data, добавив в Entity атрибут Double type, чтобы отслеживать порядок. Итак, есть ли еще какие-то шаги, необходимые для добавления атрибута количества, могут помочь решить первоначальную проблему? – MKD

+0

Привет, pbasdf. Подход, о котором вы упоминали, относится к разделу «Моделирование отношения на основе его семантики» в [Руководстве по программированию основных данных: создание отношений управляемых объектов] (https://developer.apple.com /library/ios/documentation/Cocoa/Conceptual/CoreData/index.html#//apple_ref/doc/uid/TP40001075-CH2-SW1)? – MKD