如何为一对多关系Core Data iOS添加谓词

时间:2016-03-30 07:53:05

标签: ios objective-c core-data

我在核心数据中有2个表 产品和选项

产品可以有多种选择,现在我想让产品具有特定选项。

我不知道如何为此

编写谓词where子句

enter image description here

崩溃时出现错误(***由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:'这里不允许使用多个密钥' )当我尝试下面的代码

-(Product*)getProdcutFromDB{

AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;

NSError *error;

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *orderEntity = [NSEntityDescription
                                    entityForName:@"Product" inManagedObjectContext:context];
[fetchRequest setEntity:orderEntity];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@" options.optionID == '14'"];
[fetchRequest setPredicate:predicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

Product* orderEntityForProdcut=nil;
if (fetchedObjects.count>0) {
    orderEntityForProdcut=(Product*)[fetchedObjects objectAtIndex:0];
    NSLog(@"%@",orderEntityForProdcut.productName);
    NSLog(@"%@",orderEntityForProdcut.options);

    return orderEntityForProdcut;
}

return nil;
}

2 个答案:

答案 0 :(得分:1)

为此,您必须使用SUBQUERY()

(单独的字符串是为了便于在SO上阅读。)

NSString *predicateFormat = @"SUBQUERY(options, $o, $o.optionID == %@).@count > 0"; // The "> 0" condition could also be "== 1", depending on your need.

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, optID];

旁白:最好不要在字符串中对属性名称进行硬编码。将上述内容写成:

会更好
// These would be defined somewhere that could be imported as needed.
NSString *const kOptionsKey = @"options";
NSString *const kOptionIDKey = @"optionID";

NSString *predicateFormat = @"SUBQUERY(%K, $o, $o.%K == %@).@count > 0";

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat,
                                      kOptionsKey, kOptionsIDKey, optID];

这个想法是,如果更改属性名称,则只需要更新一个常量。这也可以防止字符串中属性名称中更常见的拼写错误。

答案 1 :(得分:0)

感谢@Avi回答,我的问题已经解决了 现在更新代码在这里使用带有AND条件的多个谓词

在此代码之后,我能够获得具有optionId =“”和optionId =“”的产品列表等等.....

-(Product*)getProdcutFromDBNew{

AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;

NSError *error;

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *orderEntity = [NSEntityDescription
                                    entityForName:@"Product" inManagedObjectContext:context];
[fetchRequest setEntity:orderEntity];

// These would be defined somewhere that could be imported as needed.
NSString *const kOptionsKey = @"options";
NSString *const kOptionIDKey = @"optionID";

NSString *predicateFormat = @"SUBQUERY(%K, $o, $o.%K == %@).@count > 0";


NSPredicate *predicate1 = [NSPredicate predicateWithFormat:predicateFormat,
                          kOptionsKey, kOptionIDKey, @"12"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:predicateFormat,
                           kOptionsKey, kOptionIDKey, @"14"];


// Add the predicates to the NSArray

NSArray *subPredicates = [[NSArray alloc] initWithObjects:predicate1, predicate2, nil];

NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];



// NSPredicate* predicate = [NSPredicate predicateWithFormat:@" ANY options.name == 'Size'"];
[fetchRequest setPredicate:compoundPredicate];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

Product* orderEntityForProdcut=nil;
if (fetchedObjects.count>0) {
    orderEntityForProdcut=(Product*)[fetchedObjects objectAtIndex:0];
    NSLog(@"%@",orderEntityForProdcut.productName);
    NSLog(@"%@",orderEntityForProdcut.options);

    return orderEntityForProdcut;
}

return nil;

}