核心数据一对多关系

时间:2012-03-14 02:14:29

标签: iphone objective-c ios ios4 core-data

我的Core Data模型中有一对多的关系。一顿饭可以有多种食物。我想用一餐中的食物填充一张桌子。因此,如果1号餐有苹果,橘子和柠檬,那么桌子将由这三种食物组成。

非常感谢任何帮助,因为我完全陷入困境。

这是我的模特:

enter image description here

NSManagedObject类:

Meal.h

@class Food;

@interface Meal : NSManagedObject

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *foods;

@end

@interface Meal (CoreDataGeneratedAccessors)

- (void)addFoodsObject:(Food *)value;
- (void)removeFoodsObject:(Food *)value;
- (void)addFoods:(NSSet *)values;
- (void)removeFoods:(NSSet *)values;

@end

Food.h

@class Meal;

@interface Food : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Meal *meals;

@end

以下是我尝试尝试此操作的代码,但我遇到了一些问题。

- (NSFetchedResultsController *)fetchedResultsController 
{    
    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Food" inManagedObjectContext:_context];
    [fetchRequest setEntity:entity];

    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"Meal.foods == %@", entity]];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:@"Root"];

    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    [fetchRequest release];
    [theFetchedResultsController release];

    return _fetchedResultsController;      
}

2 个答案:

答案 0 :(得分:3)

你提到你遇到了问题,但问题不在于此;但是你的NSFetchRequest谓词看起来并不合适。 meals上定义的Food也是复数,但关系是To-one - 有点令人困惑。

您的UITableView应该使用Food中的Meal来填充,对吧?我们称之为Meal _thisMeal,然后获取谓词应为:

NSPredicate *foodPredicate = [NSPredicate predicateWithFormat:@"meals == %@",_thisMeal];
[fetchRequest setPredicate:foodPredicate];

因此,您提取的实体是Food;并且此谓词确保其meals属性是您的UITableViewController正在查找的Meal

已更新,以显示如何获取已命名的Meal

要获取名为“自定义餐”的Meal

Meal *_thisMeal = nil;
// this assumes that there should be only one Meal named "Custom Meal"
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Meal"];
NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"name = %@",@"Custom Meal"];

NSError *fetchError = nil;
NSArray *meals = [_context executeFetchRequest:request error:&fetchError];
if( fetchError )
    NSLog(@"%s - ERROR while fetching Meal: %@,%@",__FUNCTION__,fetchError,[fetchError userInfo]);
else if( [meals count] != 0 )
    _thisMeal = [meals objectAtIndex:0];

答案 1 :(得分:0)

您的膳食和食物课程是错误的。最好杀死那些并让XCode自动重新生成 这些类通过(确保您的实体被选中):

enter image description here

fetchedResultsController getter方法中,删除该行:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"Meal.foods == %@", entity]];

您通常会使用谓词来过滤数据,例如包含香蕉的食物。你当前的谓词目前还没有意义。它说“给我的食物包含一种叫做'实体'的食物,......没有意义。

因为你想吃饭......

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Food" inManagedObjectContext:_context]; 

应该是:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meal" inManagedObjectContext:_context];

(注意@"Meal")。

然后,您将通过meal.foods访问每餐中的食物。

这一行:
self.fetchedResultsController = theFetchedResultsController;
应该是:
_fetchedResultsController = theFetchedResultsController;
你所做的基本上是调用你当前的方法。