【问题标题】:Core Data filter to many ordered relationship with predicate核心数据过滤到与谓词的许多有序关系
【发布时间】:2015-07-14 14:51:37
【问题描述】:

我有一个包含 Task 和 List 的 Core Data 模型,其中 List 与 Task 具有一对多有序关系,而 Task 与 List 具有反向多对多关系。我需要以正确的顺序从给定的列表中检索任务,但经过过滤以匹配谓词。例如,如果priority 是 Task 上的一个字段,

NSPredicate* predicate = [NSPredicate predicateWithString:@"priority == HIGH"]

List* list; // already fetched 

我可以通过

NSArray* allTasks = list.tasks;
NSArray* someTasks = [allTasks filteredArrayUsingPredicate:predicate];

但这需要将所有任务拉入内存。我可以直接获取任务

NSFetchRequest* req = [[NSFetchRequest alloc] initWithEntityName:@"Task"];
[req setPredicate:[NSPredicate predicateWithFormat:@"list == %@ AND priority == HIGH", list]];
NSArray* someTasks = [context executeFetchRequest:req error:&error];

但是任务顺序没有保留。

有没有办法通过谓词过滤关系错误?

【问题讨论】:

    标签: ios core-data many-to-many nspredicate nsfetchrequest


    【解决方案1】:

    我认为下面的方法会奏效,虽然效率很低:

    1. 使用所需的谓词获取所需的Tasks,确保获取请求的returnsObjectsAsFaults 属性设置为true。
    2. 创建一个格式为“SELF IN %@”的新谓词,将任务数组(来自步骤 1)作为参数传递。
    3. 使用新谓词过滤有序集 (list.tasks)。

    这样谓词在 store 中被评估,不会在任务中出错,而顺序仍然由有序关系确定。

    【讨论】:

    • 有趣。理论上这是O(n^2),但是由于list.tasks仍然是一个错误,我想知道核心数据是否通过组合谓词来优化它
    • 我很怀疑,很遗憾。第 2 步的谓词不知道任务数组是如何派生的。但我认为 CD 会通过比较主键来做最少的事情,而不会在 Task 对象中出错。
    • 没错,仍然比触发故障更有效。感谢您的回答。我会接受的
    【解决方案2】:

    除非您使用有序关系,否则Task 实体不会以任何特定顺序返回,除非您对NSFetchRequest 进行排序。

    我建议在NSFetchRequest 中添加一个排序,并根据您的任务顺序进行排序。然后他们会以一致的顺序回来。

    顺便说一句,绝不nil 传递给error: 参数。这只会隐藏未来的潜在错误。

    【讨论】:

    • 我使用的是有序关系 List --to-many-ordered--> 任务
    • 任务有自然顺序还是完全由用户控制?
    • 感谢您的回答。它们是用户控制的。我可以在 Task 上手动存储一个 sortValue 字段,但我认为这不适用于与 List 的多对多关系。也很难维护
    • 在多对多上,您需要将隐藏的连接表变成一个真实的对象。这是一个小麻烦,但是排序值暴露给您的业务逻辑是有代价的。这与对您隐藏订单并只留下您开始时的选项的有序关系不同:/
    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多