【问题标题】:How to add predicate for one to many relation Core Data iOS如何为一对多关系Core Data iOS添加谓词
【发布时间】:2016-03-30 07:53:04
【问题描述】:

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

一个产品可以有多个选项,现在我想获得一个具有特定选项的产品。

我不知道如何为此编写谓词 where 子句

它因错误而崩溃( *** 由于未捕获的异常“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;
}

【问题讨论】:

    标签: ios objective-c core-data


    【解决方案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];
    

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

    【讨论】:

    • 谢谢,它工作得很好,您能否建议我如何在此处添加“AND”我的意思是如果我需要必须具有选项 id 12,13 和 14 的产品
    • 只需分别定义每个谓词,然后使用NSCompoundPredicate 组合它们。
    • 你能提供一个我是新来谓词的样本吗:(
    • NSPredicate *predicate1 = [NSPredicate predicateWithFormat:predicateFormat, kOptionsKey, kOptionIDKey, @"15"]; NSPredicate *predicate2 = [NSPredicate predicateWithFormat:predicateFormat, kOptionsKey, kOptionIDKey, @"14"]; // 添加谓词到 NSArray NSArray *subPredicates = [[NSArray alloc] initWithObjects:predicate1, predicate2, nil]; NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
    • 嗨,Avi,我可以在 SUBQuery 中添加属性,例如 ID 和名称,最终谓词将是这个组合的数组吗???
    【解决方案2】:

    感谢@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;
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多