Базовые данные: Извлечь все сущности в отношении многих к определенному объекту? - PullRequest
4 голосов
/ 30 декабря 2010

в моем приложении для iPhone я использую простую модель базовых данных с двумя сущностями ( Item и Property ):

Item
имя
свойства

свойство
имя
значение
элемент

Элемент имеет один атрибут (имя) и одно отношение «один ко многим» ( properties ).Его обратная зависимость вещь . Свойство имеет два атрибута в соответствии с обратной зависимостью.

Теперь я хочу показать мои данные в табличных представлениях на двух уровнях.Первый перечисляет все элементы;Когда выбрана одна строка, новый UITableViewController помещается в стек моего UINavigationController.Предполагается, что новый UITableView отображает все свойства (то есть их имена) выбранного элемента.

Для этого я использую NSFetchedResultsController, хранящийся в переменной экземпляра.На первом уровне все работает нормально при настройке NSFetchedResultsController следующим образом:

-(NSFetchedResultsController *) fetchedResultsController {
    if (fetchedResultsController) return fetchedResultsController;

    // goal: tell the FRC to fetch all item objects.
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.moContext];
    [fetch setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetch setFetchBatchSize:10];

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
    self.fetchedResultsController = frController;
    fetchedResultsController.delegate = self;

    [sort release];
    [frController release];
    [fetch release];

    return fetchedResultsController;
}

Однако на UITableView второго уровня я, кажется, что-то делаю не так.Я реализовал fetchedresultsController подобным образом:

-(NSFetchedResultsController *) fetchedResultsController {
    if (fetchedResultsController) return fetchedResultsController;

    // goal: tell the FRC to fetch all property objects that belong to the previously selected item
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];

    // fetch all Property entities.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.moContext];
    [fetch setEntity:entity];

    // limit to those entities that belong to the particular item
    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"item.name like '%@'",self.item.name]];
    [fetch setPredicate:predicate];

    // sort it. Boring.
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]];

    NSError *error = nil;
    NSLog(@"%d entities found.",[self.moContext countForFetchRequest:fetch error:&error]);
    // logs "3 entities found."; I added those properties before. See below for my saving "problem".
    if (error) NSLog("%@",error);
    // no error, thus nothing logged.

    [fetch setFetchBatchSize:20];

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
    self.fetchedResultsController = frController;
    fetchedResultsController.delegate = self;

    [sort release];
    [frController release];
    [fetch release];

    return fetchedResultsController;
}

Теперь это становится странным.Приведенный выше оператор NSLog возвращает мне правильное количество свойств для выбранного элемента.Тем не менее, метод UITableViewDelegate говорит мне, что нет никаких свойств:

-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    NSLog(@"Found %d properties for item \"%@\". Should have found %d.",[sectionInfo numberOfObjects], self.item.name, [self.item.properties count]);
    // logs "Found 0 properties for item "item". Should have found 3."
    return [sectionInfo numberOfObjects];
}

Та же самая реализация прекрасно работает на первом уровне.

Становится еще страннее.Я реализовал какой-то интерфейс для добавления свойств.Я создаю новый экземпляр Property через Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext];, устанавливаю отношения и вызываю [self.moContext save:&error].Кажется, это работает, поскольку error по-прежнему nil и объект сохраняется (я вижу количество свойств при регистрации экземпляра Item , см. Выше).Однако методы делегата не запускаются.Это кажется мне из-за возможно испорченного fetchRequest (Controller).

Есть идеи?Я испортил второй запрос на получение?Является ли это правильным способом извлечения всех сущностей в отношении «многие ко» для конкретного экземпляра?

1 Ответ

2 голосов
/ 30 декабря 2010

Вам необходимо выполнить выборку для контроллера табличного представления:

// ...create the fetch results controller...    
NSError *fetchRequestError;
BOOL success = [fetchedResultsController performFetch:&fetchRequestError];
...