【问题标题】:create a Compound Predicate in coreData xcode iphone在coreData xcode iphone中创建一个复合谓词
【发布时间】:2013-07-17 10:32:35
【问题描述】:

您好,我正在处理 3 个实体(班级、学生、考试记录)的核心数据,它们的关系区域为:

Class<------>> Students <------> ExamRecord

我创建了一个谓词来获取第 5 班的学生列表。

NSString * fmt2 = @"studentsToClass.className=%@";
NSPredicate * p2 = [NSPredicate predicateWithFormat:fmt2,@"5th",nil];

有了这个,我得到了第 5 班的所有学生

现在我还想对获取的学生应用另一个过滤器。

获取考试记录“结果”为“通过”的学生。结果是 ExamResult 实体中学生的属性

我如何在这个中使用复合谓词?

如有错误请指正

任何帮助将不胜感激

谢谢

【问题讨论】:

    标签: iphone ios core-data nspredicate


    【解决方案1】:

    您可以使用复合谓词:

    NSPredicate *p1 = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@", @"5th"];
    NSPredicate *p2 = [NSPredicate predicateWithFormat:@"studentsToExamRecord.result = %@", @"Pass"];
    NSPredicate *p = [NSCompoundPredicate andPredicateWithSubpredicates: @[p1, p2]];
    

    或者您只需将测试与“AND”结合起来:

    NSPredicate *p = [NSPredicate predicateWithFormat:@"studentsToClass.className = %@ AND studentsToExamRecord.result = %@",
          @"5th", @"Pass"];
    

    注意predicateWithFormat 的参数列表不是nil-终止的。 参数的数量由格式中的格式说明符的数量决定 字符串。

    【讨论】:

    • @Fogmeister:我很想知道。
    • @MartinR 感谢您的帮助,但我仍然无法获取 Student 的结果。我的谓词变为:studentsToClass.className == "5th" AND studentsToExamRecord.result == "Pass" 请帮助并纠正我哪里错了
    • @sagar:你得到错误还是没有结果?也许展示实体是如何定义的以及如何创建对象。如果省略谓词,你会得到所有对象吗?
    • 如果我申请了studentsToClass.className == "5th then I get all the students else no records are found
    • @sagar:但谓词看起来不错。您确定设置了从学生到 ExamRecord 的关系吗? “结果”属性的值是真的“通过”还是小写?
    【解决方案2】:

    首先,您引用的谓词确实已经错了。您应该引用托管对象,而不是其属性(即不是 Classname)。应该是:

    [NSPredicate predicateWithFormat:@"class = %@", classObject]; 
    

    此外,您应该为变量和属性选择更易读的名称。所以,不是fmt2,而是formattingString。不是studentsToClass,而是form(“class”是objective-C中的一个特殊词)。你明白了。

    所以你想要的复合谓词是这样完成的(短版):

    [NSPredicate predicateWithFormat:@"class = %@ && record.result = %@",
             classObject, @"Pass"]; 
    

    复杂的版本,如果你真的需要更高层次的抽象(我怀疑):

    classPredicate = [NSPredicate predicateWithFormat:@"class = %@", classObject]; 
    resultPredicate = [NSPredicate predicateWithFormat:@"record.result = %@", @"Pass"];
    finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:
        @[classPredicate, resultPredicate]];
    

    【讨论】:

    • 如果两个子谓词都是可选的,即 A OR B 而不是 A AND B,如何将它们合并为一个。
    • 那将是一个单独的 SOF 问题 ;-)。
    • 是的,我发现:) 它是使用 orPredicateWithSubpredicates 完成的:
    【解决方案3】:

    首先,您不应该真正将student - class 关系称为studentsToClass。关系的名称应该反映另一端的对象类型。

    例如

    在这种情况下,StudentClass 的关系应称为 class,因为该对象只有一个 Class 实体。 逆关系不应称为classToStudent,而应称为students,因为存在多个StudentsNSSet

    编辑

    只是补充一下。关系的名称应该解释它为什么存在。我们可以看到这种关系是从班级到学生的,但如果你称它为“classToStudent”,它并不能解释任何事情。另外,如果您在班级与学生之间有第二个关系怎么办?你这叫什么。如果你称它为attendeespupilsattendingStudents 等。它给出了关系的含义。

    解决方案

    在这个例子中,我将按照我如何称呼它们来称呼它们,你会发现它更容易理解......

    无论如何...

    NSPredicate *classPredicate = [NSPredicate predicateWithFormat:@"class.className = %@", @"5th"];
    NSPredicate *passPredicate = [NSPredicate predicateWithFormat:@"result.name = %@", @"Pass"];
    
    NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[classPredicate, passPredicate]];
    

    【讨论】:

    • 感谢您的帮助但我仍然无法获取学生。我的谓词变为:studentsToClass.className == "5th" AND studentsToExamRecord.result == "Pass" 请帮助并纠正我的错误
    【解决方案4】:

    谓词也可以使用复合谓词嵌套(对于 Swift

            let orPredicate = NSCompoundPredicate(type: .or, subpredicates: [date_1KeyPredicate, date_2KeyPredicate])
    
            let functionKeyPredicate = NSPredicate(format: "function_name = %@", self.title!)
    
            let andPredicate = NSCompoundPredicate(type: .and, subpredicates: [orPredicate, functionKeyPredicate])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-22
      相关资源
      最近更新 更多