Подтвердить что ты не робот

Как вы управляете и используете отношения "многие-многие" с основными данными?

Я создаю приложение и пытаюсь использовать основные данные, потому что кажется, что он одобрен objective-C способом создания системы хранения данных. Вариант использования, который я использую, связан с отношениями "многие-многие", как обычно вы видите в стандартной системе SQL. Я понимаю, что цель C не является базой данных и работает по-разному. Я также рассмотрел документацию здесь:

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW10

И еще несколько других мест. И все же у меня все еще есть проблемы. Может ли кто-нибудь объяснить мне, что вы будете делать, если у вас есть вариант использования, где вам нужно будет использовать таблицу перекрестных ссылок SQL? Например:

Менеджеры | Сотрудники

У менеджера может быть несколько сотрудников, но у сотрудников также может быть несколько менеджеров. В SQL я бы создал таблицу перекрестных ссылок, а затем использовал это.

Пример: http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php

Может кто-нибудь объяснить, как вы могли бы это сделать в данных Core?

В соответствии с основной документацией данных они говорят следующее:

"Вы определяете отношения" многие-ко-многим ", используя отношения" два-ко-многим ". Отношение" от первого до многих "происходит от первого объекта ко второму объекту. Второе отношение ко многим относится ко второму объекту к первому (если у вас есть фон в управлении базой данных, и это вызывает у вас беспокойство, не беспокойтесь: если вы используете хранилище SQLite, Core Data автоматически создает промежуточную таблицу соединений для вы.)"

Но, кроме "не беспокоясь", я не знаю, как это могло бы работать?

4b9b3361

Ответ 1

Питер: "У меня девять боссов, Боб". Боб: "Скажи еще раз?" Питер: "Девять".

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

Если вы используете пользовательский подкласс NSManagedObject, вы можете объявить свойства как задокументированные. Тогда вы можете просто сказать:

NSSet *mgrsEmployees = mgr.employees;
NSSet *employeesMgrs = employee.managers;

Это не даст вам всех сотрудников и всех менеджеров, только всех сотрудников этого менеджера и всех менеджеров для этого сотрудника. Чтобы изменить отношения:

[mgr addEmployeesObject:newEmployee];
[newEmployee addManagersObject:mgr]; // not necessary, automatic if you define inverse

[mgr removeEmployeesObject:transferredEmployee];
[transferredEmployee removeManagersObject:mgr]; // not necessary
[newMgr addEmployeesObject:transferredEmployee];
[transferredEmployee addManagersObject:newMgr]; // not necessary

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

Если вы не используете пользовательский подкласс, доступ к нему будет немного более подробным

NSSet *mgrsEmployees = [mgr valueForKey:@"employees"];
NSSet *employeesMgrs = [employee valueForKey:@"managers"];

NSMutableSet *changeMgrsEmployees = [mgr mutableSetValueForKey:@"employees"];
[changeMgrsEmployees addObject:newEmployee];
// not necessary
NSMutableSet *changeEmployeesMgrs = [employee mutableSetValueForKey:@"managers"];
[changeEmployeesMgrs addObject:mgr];

Etc.

Ответ 2

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

Если ваш вопрос "как это может работать", вам может показаться полезным взглянуть на базу данных sqlite, созданную из вашей модели, чтобы узнать, как это происходит. CoreData очень хорош в том, что вы не должны заботиться о деталях, но если вы настаиваете на понимании деталей, ничего не мешает вам смотреть на данные, чтобы увидеть, что они делают.

Как только у вас есть это место, вы должны пересечь отношения по мере необходимости, чтобы получить нужные вам атрибуты. Вы можете сделать это в коде, используя экземпляры NSManagedObject. Например:

NSManagedObject *manager = // get a reference to a manager here
NSSet *employees = [manager valueForKey:@"employees"];
for (NSManagedObject *employee in employees) {
    NSString *employeeName = [employee valueForKey:@"name"];
    // Do whatever else you want here
}

Этот пример также можно упростить, используя прямой доступ к свойствам, а не синтаксис KVO, но вы получите эту идею.

Если вы хотите более точно переходить от этого отношения "многие ко многим" как часть запроса на выборку, вы можете сделать некоторые вещи с предикатами, чтобы получить то, что вы хотите. Обратитесь к руководству по программированию предикатов Apple для примеров того, что вы можете поместить в предикат

Ответ 3

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

@interface Employee :  NSManagedObject  
{

}

@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSSet* managers;

@interface Manager :  NSManagedObject  
{

}

@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSSet* employees;

Итак, скажем, вы хотели получить всех сотрудников для менеджера номер 1, вам просто нужно получить объект-менеджер из базы данных:

NSNumber *managerID = [NSNumber numberWithInt:1];
NSEntityDescription * entityDescription = [NSEntityDescription entityForName:@"Manager"                                                       inManagedObjectContext:managedObjectContext]; 
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];  
[request setEntity:entityDescription];  
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %d", @"id", managerID];   
[request setPredicate:predicate];
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
Manager *manager = [array objectAtIndex:0];

и тогда у вас будут все сотрудники в собственности сотрудников:

NSSet *allHisEmployees = manager.employees;

Было бы точно так же получить менеджеров для данного сотрудника.

Я надеюсь, что это очистит вещи.

Ответ 4

Простой ответ заключается в том, чтобы пометить отношение как одно для многих с обоих концов при настройке основных данных в xCode. Это по существу создает много-много. Это в яблочном документе где-то, но я не могу найти URL.

Ответ 5

Возможно, вы застряли в том, как перейти от области абстрактных моделей данных к набору объектов, которые вы используете в коде. Если это так, посмотрите на использование mogenerator:

http://rentzsch.github.com/mogenerator/

Это утилита командной строки (не уверен, насколько хорошо работает XCode-интеграция в эти дни), где вы указываете ее на модели, и она дает вам множество объектов данных, которые вы можете использовать. Вы должны иметь имя объекта для каждого объекта в дополнение к имени объекта.

Сгенерированные объекты данных имеют вызовы, такие как employee.managers, которые предоставят вам набор объектов менеджера для сотрудника и наоборот.