Обсуждение

We use cookies. Read the Privacy and Cookie Policy

Обсуждение

В Core Data могут существовать следующие виды отношений: «один к одному» (one-to-one), обратное отношение «один ко многим» или обратное отношение «многие ко многим». Далее приведены жизненные примеры каждой разновидности отношений.

• Отношение «один к одному» — существует между человеком и его носом. У каждого человека может быть только один нос, и каждый нос может принадлежать только одному человеку.

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

 Обратное отношение «многие ко многим» — возникает между человеком и автомобилем. Одна машина может использоваться несколькими людьми, а один человек может пользоваться несколькими машинами.

В Core Data можно создавать отношения «один к одному», но я категорически не рекомендую этого делать. Возвращаясь к недавнему примеру с носом, необходимо отметить, что человек будет знать, чей нос торчит у него на лице, а вот нос не будет знать, кому он принадлежит. Обратите внимание на то, что эта система отношений «один к одному» отличается от взаимно однозначных отношений, с которыми вы могли столкнуться в других системах управления базами данных: объект A и объект B будут взаимосвязаны друг с другом, если между ними существует отношение «один к одному». В Core Data при отношении «один к одному» объект A будет знать, что связан с объектом B, но не наоборот. В объектно-ориентированном языке, таком как Objective-C, всегда лучше создавать обратные отношения, такие, которые позволяют дочерним элементам обращаться к родительским. При отношении «один ко многим» объект, который может быть ассоциирован с рядом других объектов, будет удерживать это множество объектов. Это будет множество типа NSSet. Хотя при отношениях «один к одному» оба объекта, состоящие в таких отношениях, сохраняют ссылку друг на друга, так как используют правильное имя класса «напарника», это отношение все равно принадлежит к типу «один к одному», и один объект может быть представлен в другом путем простого указания своего имени класса.

Итак, создадим такую модель данных, в которой используются преимущества обратного отношения «один ко многим».

1. Найдите в Xcode файл xcdatamodel, созданный системой в самом начале работы с проектом Core Data. Это было показано во введении к данной главе (создание такого проекта описано в разделе 16.1).

2. Откройте в редакторе файл модели данных, щелкнув на нем кнопкой мыши.

3. Удалите все созданные ранее сущности, выделяя их и нажимая клавишу Delete.

4. Создайте новую сущность и назовите ее Employee (Сотрудник). Создайте для этой сущности три атрибута, которые будут называться firstName (типа String), lastName (типа String) и age (типа Integer 32) (рис. 16.13).

Рис. 16.13. Сущность Employee с тремя атрибутами

5. Создайте сущность под названием Manager (Менеджер) с такими же атрибутами, как и у сущности Employee: firstName (типа String), lastName (типа String) и age (типа Integer 32) (рис. 16.14).

Рис. 16.14. Сущность Manager с тремя атрибутами

6. Создайте новое отношение для сущности Manager. Для этого сначала нужно выбрать данную сущность из списка, а потом нажать кнопку + в нижней части области Relationships (Отношения) (рис. 16.15).

Рис. 16.15. Добавление нового отношения к сущности Manager

7. В качестве имени нового отношения задайте employees (Сотрудники) (рис. 16.16).

Рис. 16.16. Изменение имени нового отношения типа «менеджер к сотрудникам»

8. Выберите сущность Employee и создайте для нее новое отношение. Назовите это отношение manager (рис. 16.17).

Рис. 16.17. Изменение имени нового отношения между сотрудниками и менеджером

9. Выберите сущность Manager, а потом выделите отношение employees для Manager. В области Relationships (Отношения) выберите параметр Employee (Сотрудник) в раскрывающемся меню Destination (Назначение). Именно так — ведь в этом отношении мы хотим соединить сущности Manager и Employee. В столбце Inverse (Обратные отношения) укажите значение manager (так как отношение manager будет связывать сотрудника (Employee) с менеджером (Manager)). Наконец, установите флажок To-Many Relationship (Отношение ко многим) в инспекторе модели данных (см. раздел 16.1). Результаты приведены на рис. 16.18.

Рис. 16.18. Обратное отношение, установленное между менеджером и сотрудниками

10. Выделите обе сущности (Employee и Manager), выполните команду File — New File (Файл — Новый файл) и создайте классы управляемых объектов для вашей модели, как описано в разделе 16.2.

Создав обратное отношение «один ко многим», откройте. h-файл вашей сущности Employee:

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

@class Manager;

@interface Employee: NSManagedObject

@property (nonatomic, retain) NSNumber * age;

@property (nonatomic, retain) NSString * firstName;

@property (nonatomic, retain) NSString * lastName;

@property (nonatomic, retain) Manager *manager;

@end

Как видите, в этом файле появилось новое свойство. Оно называется manager и относится к типу Manager. Таким образом, начиная с данного момента мы при наличии ссылки на конкретный объект типа Employee можем получить доступ к свойству manager, а через него — к объекту Manager данного конкретного сотрудника (если менеджер есть). Рассмотрим. h-файл сущности Manager:

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

@class Employee;

@interface Manager: NSManagedObject

@property (nonatomic, retain) NSNumber * age;

@property (nonatomic, retain) NSString * firstName;

@property (nonatomic, retain) NSString * lastName;

@property (nonatomic, retain) NSSet *employees;

@end

@interface Manager (CoreDataGeneratedAccessors)

— (void)addFKManagerToEmployeesObject:(Employee *)value;

— (void)removeFKManagerToEmployeesObject:(Employee *)value;

— (void)addFKManagerToEmployees:(NSSet *)values;

— (void)removeFKManagerToEmployees:(NSSet *)values;

@end

Для сущности Manager также создается свойство employees. Тип данных этого объекта — NSSet. Это означает, что свойство employees любого экземпляра сущности Manager может содержать от 1 до N сущностей Employee. В этом и заключается принцип отношения «один ко многим»: один менеджер, несколько сотрудников.

Другой тип отношений, которые, возможно, потребуется реализовать, называется «многие ко многим». По сравнению с отношением Manager к Employee при отношении «многие ко многим» один менеджер может иметь N сотрудников, а каждый сотрудник может подчиняться N менеджерам. Чтобы организовать такие отношения, выполните те же инструкции, что и при создании отношения «один ко многим», но выделите сущность Employee, а потом отношение manager. Измените это название на managers и установите флажок To-Many Relationship (Отношение ко многим) (рис. 16.19). Теперь стрелка будет заострена с обоих концов.

Рис. 16.19. Создание отношения «многие ко многим» между сущностями Manager и Employee

Теперь, открыв файл Employee.h, вы увидите, что его содержимое изменилось:

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

@class Manager;

@interface Employee: NSManagedObject

@property (nonatomic, retain) NSNumber * age;

@property (nonatomic, retain) NSString * firstName;

@property (nonatomic, retain) NSString * lastName;

@property (nonatomic, retain) NSSet *managers;

@end

@interface Employee (CoreDataGeneratedAccessors)

— (void)addManagersObject:(Manager *)value;

— (void)removeManagersObject:(Manager *)value;

— (void)addManagers:(NSSet *)values;

— (void)removeManagers:(NSSet *)values;

@end

Как видите, свойство managers сущности Person теперь представляет собой множество. Поскольку отношение сотрудника к его менеджерам — это множество и такое же отношение существует между менеджером и сотрудниками, здесь мы имеем пример отношения «многие ко многим»

В коде, написанном для отношения «один ко многим», можно просто создать новый управляемый объект Manager (о том, как вставлять объекты в контекст управляемых объектов, рассказано в разделе 16.3), сохранить его в контексте управляемых объектов, а потом соединить с парой управляемых объектов Employee — и их тоже сохранить в контексте. Теперь, чтобы ассоциировать менеджера с сотрудником, задайте в качестве значения для свойства FKEmployeeToManager, относящегося к экземпляру Employee, экземпляр управляемого объекта Manager. После этого фреймворк Core Data сам создаст необходимое отношение.

Если потребуется получить всех сотрудников (типа Employee), ассоциированных с объектом-менеджером (типа Manager), нужно будет просто воспользоваться методом экземпляра allObjects, относящимся к свойству FKManagerToEmployees вашего объекта-менеджера. Это объект типа NSSet, поэтому можно применить метод экземпляра allObjects, чтобы получить массив всех объектов-сотрудников, ассоциированных с конкретным объектом-менеджером.

Данный текст является ознакомительным фрагментом.