Кросс-магазин слабых отношений с Fetched Properties? - PullRequest
4 голосов
/ 21 ноября 2011

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

У меня есть модель Core Data, использующая 2 конфигурации:

  • модель данных config 1: UserData (объекты, относящиеся к пользователю)

  • модель данных config 2: ReferenceData (объекты, относящиеся к самому приложению)

Я установил 2 разных постоянных хранилища SQLite для обеих конфигураций.

  • Конфигурация UserData (и хранилище) содержит сущность "Пользователь"

  • Конфигурация ReferenceData (и хранилище) содержит сущности «Тип» и «Элемент».

Я хотел бы создать две односторонние слабые связи, как показано ниже:

  • «Пользователь» имеет уникальный «Тип»

  • «Пользователь» имеет много «Предметов»

Вот мои вопросы:

  • Как настроить мои свойства?

  • Нужно ли мне 2 свойства для каждого отношения (одно для хранения уникального идентификатора, а другое для доступа к полученным результатам)?

  • Можно ли заказать эти слабые отношения?

  • Может ли кто-нибудь дать мне пример реализации этого?

Как продолжение ответа Маркуса:

Просматривая форумы и документы, я прочитал, что должен использовать URI-представление моего экземпляра сущности вместо objectID. В чем причина этого?

// Get the URI of my object to reference 
NSURL * uriObjectB [[myObjectB objectID] URIRepresentation];

Далее, мне интересно, как мне сохранить мой объект B URI (NSURL) в моем родительском объекте A как слабое отношение? Какой тип атрибута мне следует использовать? Как мне конвертировать это? Я слышал об архиве ...?

Затем, позже я должен получить управляемый объект таким же образом (путем преобразования / разархивирования URIRepresentation) и получить объект из URI

// Get the Object ID from the URI 
NSManagedObjectID* idObjectB = [storeCoordinator managedObjectIDForURIRepresentation:[[myManagedObject objectID] URIRepresentation]];

// Get the Managed Object for the idOjectB ...

И, наконец, что не менее важно, я должен объявить два свойства в моей сущности A, одно для сохранения потребностей URI, а другое для получения объекта direclty B?

NSURL * uriObjectB [objectA uriObjectB];

ObjectB * myObjectB = [objectA objectB];

Как вы понимаете, я очень скучаю по простому примеру реализации этих слабых отношений! Буду очень признателен за помощь.

Ответы [ 2 ]

6 голосов
/ 21 ноября 2011

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

Чтобы создать мягкие ссылки на хранилища (они не обязательно должны быть SQLite, но это хорошая идея для общей производительности приложения), вам потребуется какой-то уникальный ключ, на который можно ссылаться с другой стороны; старый добрый внешний ключ.

Оттуда вы можете создать извлеченное свойство в модели для ссылки на сущность.

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

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

Пример

Представьте, что у вас есть сущность UserBar в хранилище пользователей и сущность RefBar в хранилище ссылок. Затем RefBar будет иметь «связь» fetchedProperty с UserBar, создавая тем самым связь ToOne.

UserBar
----------
refBarID : NSInteger

RefBar
--------
identifier : NSInteger

Затем вы можете создать извлеченное свойство для сущности RefBar в моделере с предикатом:

$ FETCHED_PROPERTY.refBarID == идентификатор

Позволяет назвать предикат "userBarFetched"

Теперь это вернет массив, поэтому мы хотим добавить вспомогательный метод в RefBar

@class UserBar;

@interface RefBar : NSManagedObject

- (UserBar*)userBar;

@end

@implementation RefBar

- (UserBar*)userBar
{
    NSArray *fetched = [self valueForKey:@"userBarFetched"];
    return [fetched lastObject];
}

@end

Создать ToMany тоже самое, за исключением того, что ваш удобный метод вернул бы массив, и вы должны отсортировать массив перед его возвратом.

Как упоминалось Heath Borders , можно добавить сортировку к NSFetchedProperty, если вы хотите, но вы должны сделать это в коде. Лично я всегда считал это расточительным и не использую эту функцию. Возможно, было бы более полезно, если бы я мог установить сортировку в моделере.

Использование ObjectID

Я не рекомендую использовать ObjectID или URIRпредставление. ObjectID (и, следовательно, представление URIR этого ObjectID) может и будет изменяться. Всякий раз, когда вы переносите базу данных, это значение будет меняться. Вам гораздо лучше создать неизменяемый GUID.

Слабые отношения

Вам нужно только одно значение на стороне M отношения, в котором хранится внешний идентификатор. В вашем подклассе объектов вам нужно только реализовать средства доступа, которые извлекают объект (или объекты).

0 голосов
/ 21 ноября 2011

Я бы выбрал только одно хранилище.

Для хранения вещей в облаке вам в любом случае придется сериализовать данные в виде операторов JSON или SQL или любой другой схемы, которую вы предпочитаете.

Вам понадобится локальная копия данных на устройстве пользователя, чтобы он мог получить к ней быстрый и автономный доступ.Облачное хранилище может иметь только пользовательский объект, в то время как локальное хранилище (часть приложения) также может иметь эталонный объект.

У меня есть аналогичный проект с огромным эталонным хранилищем (20000 записей) с географической информацией.и пользовательский контент ("сообщения").Я пользуюсь одним магазином.Когда я отправляю приложение, сущность "posts" также определяется, но пуста.Когда я обновляю модель данных, я просто заново генерирую весь справочный магазин перед отправкой.

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

...