Два контекста, 1 постоянный магазин: повторяющиеся извлеченные записи - PullRequest
1 голос
/ 07 сентября 2011

Я пытаюсь создать способ для пользователей импортировать контакты на свой телефон. Как это работает, это:

  • Существует два контекста управляемого объекта. «Реальный» контекст содержит текущие данные в своей адресной книге. «Другой» контекст имеет входящие данные из другого источника. Оба используют один и тот же PersistentStoreCoordinator.

  • Я сопоставляю людей по электронной почте, поэтому, если контакт в «реальном» контексте совпадает с одним в «другом», я не сохраняю другого.

  • Когда я запускаю программу, у меня есть две записи в «реальном» контексте, которые я могу получить в порядке.

  • Затем я импортирую два других контакта и добавляю их в «другой» контекст.

  • Когда я выполняю операцию выборки для «другого» контекста, я получаю ЧЕТЫРЕ результата - два из «реального» контекста и два, которые я только что добавил в «другой» контекст.

  • Однако, когда я объединяю изменения, моя схема обнаружения дубликатов работает.

Что-то мне не хватает в моем понимании Базовых Данных? Как я могу сделать так, чтобы мои запросы о «другом» контексте просто возвращали новые результаты.

Полный код действительно длинный, но вот важная часть:

AppDelegate *appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];

// Check to see the original data
NSManagedObjectContext *realContext = [appDel managedObjectContext];
NSFetchRequest *usersFetch= [[[NSFetchRequest alloc] init] autorelease];
[usersFetch setEntity:[NSEntityDescription entityForName:@"User" inManagedObjectContext:realContext]];
[usersFetch setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"email" ascending:YES]]];

NSArray *users = [realContext executeFetchRequest:usersFetch error:&error];
[usersFetch release];
NSLog(@"%@",users);   // Returns 2 original objects already in database


otherContext = [[NSManagedObjectContext alloc] init];
[otherContext setPersistentStoreCoordinator:[[appDel managedObjectContext] persistentStoreCoordinator]];

for (contacts in fetchedData){
    User *newUser = (User*)[NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:otherContext];
    newUser.email = fetchedData.email;
    newUser.firstName = fetchedData.firstName;
    // etc.
}

NSFetchRequest *newUsersFetch = [[[NSFetchRequest alloc] init] autorelease];
[newUsersFetch setEntity:[NSEntityDescription entityForName:@"User" inManagedObjectContext:otherContext]];
[newUsersFetch setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"email" ascending:YES]]];
NSLog(@"%@",[otherContext registeredObjects]);   // 2 objects that were just added
NSArray *newUsers = [otherContext executeFetchRequest:newUsersFetch error:&error];
NSLog(@"%@",[otherContext registeredObjects]);  // 4 objects - added AND original
NSLog(@"Count: %i",[newUsers count]);                  // Count: 4

1 Ответ

1 голос
/ 07 сентября 2011

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

Это особенно верно для выборок, которые идут прямо в магазин, чтобы найти объекты.Ваш код работает должным образом, если вы вызываете save в контексте other.Как только вы сохраняете объект, он попадает в постоянное хранилище и будет отображаться во всех выборках всей сущности.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...