Дублирующиеся записи для основного контроллера представления таблицы данных и как справиться с этим с помощью NSFetchedResultsController
У меня есть простое приложение со следующей предпосылкой и несколькими незначительными проблемами:
- У меня есть 4 вкладки, каждая с табличным представлением, отображающим различную информацию, и каждая с кнопкой плюс, идущей модально к одному и тому же контроллеру представления, что позволяет пользователям добавлять информацию в приложение.
- Пользователь добавляет имя, заголовок, дату и сумму в контроллере представления, и когда он нажимает сохранить, он сохраняется в табличном представлении основных данных.
Первая вкладка отображает ВСЕ для битов информации выше (Имя, Название, Дата, Сумма) в пользовательской ячейке таблицы с метками и т. Д. Это хорошо работает.
Вторая вкладка отображает только информацию об имени, третья вкладка отображает только заголовки. Таким образом, пользователь видит все на первой вкладке, но только "имена" на второй вкладке, которые они могут выбрать, чтобы собрать информацию об этом имени.
Приложение работает хорошо, когда для имени (или даты, или заголовка) есть только одна запись, но когда я добавляю вторую запись, она дублируется на вкладке "Имя".
Например, если у меня есть запись для Джона Смита только с одной записью, она будет отображаться на вкладке "Имя" с одной записью, а когда я вхожу, она отображает только те транзакции, к которым прикреплено имя Джона (1 в этом дело). Все хорошо.
Однако, если я добавлю еще одну запись для Джона (пишется точно так же), она будет обрабатываться как отдельная запись, и внезапно на вкладке "Имя" появятся 2 записи Джона.
Я не поместил никаких уникальных идентификаторов в атрибуты базовой модели данных, но должен ли я это сделать, или я мог бы просто использовать предикат, чтобы спросить: "Если это уже существует, не отображать его дважды" на вкладке "Имя" Бар?
Любая помощь будет высоко ценится!
Редактировать:
Вот запрос fetchRequest для вкладки Имя:
- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"whoBy.name" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
Как мы видим, здесь нет предикатов или чего-то подобного. Мне нужна простая проверка, чтобы увидеть, "если имя существует, не добавляйте его дважды" в представлении таблицы "Имя". Я надеюсь это имеет смысл?
2 ответа
Запись дублируется, потому что в Names
Вкладка вы запрашиваете Transactions
таблицы, а затем получить имя человека, который сделал эту транзакцию. Поскольку у Джона есть две транзакции, вы получаете его имя дважды.
Попробуйте что-то вроде этого:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
Таким образом, вы должны получить каждое имя (лицо) только один раз (при условии, что отношения между Именами и Транзакциями однозначны).
РЕДАКТИРОВАТЬ: Каждый раз, когда вы создаете Transaction
Есть две вещи, которые могут произойти с Person
:
- это может быть новым
Person
и вы должны создать новую сущность; или же, - это новый
Person
,
Логика такова, и вам придется выяснить код:
Когда пользователь добавляет
Transaction
, вам нужно проверить, для нового или уже существующего - если это уже существующий, может быть, он может выбрать его из спискаPersons
(и когда он выбирает человека, вы получаете егоNSManagedObjectID
). Если это новый, вы создаете его на месте.После создания
Transaction
объект, вам нужно добавитьPerson
возражать против его отношений. Если я правильно видел, у вас естьwhoBy
отношения вTransaction
объект. Установите его наPerson
объект, который вы получили в шаге 1.Установите все остальные поля
Transaction
объект (сумма и т. д.).Спасти
NSManagedObjectContext
когда вы закончите со всем этим.
Что вы делаете в своем коде на данный момент, это создать новый Person
для каждого Transaction
Вот почему вы видите несколько записей с одним именем.
Да, вы можете сказать CoreData, что вы хотите только отдельные значения, установив:
NSFetchRequest *request;
request.propertiesToFetch = [NSArray arrayWithObject:@"Name"];
request.returnsDistinctResults = YES;
request.resultType = NSDictionaryResultType;
...
Но если вы не хотите, чтобы в базе данных было 2 Джона, лучше не помещать их туда, чем фильтровать результаты. Поэтому, когда вы вставляете данные, проверьте, есть ли у вас эта запись, и если вы ее не вставили (вы можете просто обновить эту запись)...