0

这个让我莫名其妙:

我有一个核心数据集,我使用以下代码搜索/过滤:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Lead" inManagedObjectContext:moc]];
NSString *predicateString = [NSString stringWithFormat:@"("
                       "(isLocalVersion == %@) AND (LeadStatusID =='Active')"
                       ") AND ("
                       "(LeadID contains[cd] '%@')"
                       "OR (AccountNumber contains[cd] '%@')"
                       "OR (ANY contactItems.FirstName contains[cd] '%@')"
                       "OR (ANY contactItems.LastName contains[cd] '%@')"
                       "OR (ANY addressItems.Address1 contains[cd] '%@')"
                       "OR (ANY addressItems.City contains[cd] '%@')"
                       ")", [NSNumber numberWithBool:YES], sTerm, sTerm, sTerm, sTerm, sTerm, sTerm];

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
[fetchRequest setPredicate:predicate];

NSError *error = nil;
NSArray *leads = nil;
@try {
    leads = [moc executeFetchRequest:fetchRequest error:&error];
}
@catch (NSException *exception) {
    LogSevere(@"Error Executing Fetch Request: %@", exception);
    leads = [NSArray array];
}
@finally {
    [fetchRequest release];
}

sTerm 只是一个NSString.

这在 95% 的时间里都有效,但是每隔一段时间它就会捕获一个NSInvalidArgumentException: Can't use in/contains operator with collection 10076173 (not a collection).

谓词字符串格式如下:

((isLocalVersion == 1) AND (LeadStatusID =='Active')) AND ((LeadID contains[cd] 'i')OR (AccountNumber contains[cd] 'i')OR (ANY contactItems.FirstName contains[cd] 'i')OR (ANY contactItems.LastName contains[cd] 'i')OR (ANY addressItems.Address1 contains[cd] 'i')OR (ANY addressItems.City contains[cd] 'i'))

我的捕获让我不会崩溃,只返回 0 个结果,但这不是最佳的。有没有人见过这个?

我唯一的线索是,它似乎发生在我修改(并保存)核心数据中的记录之后(再次只是有时)。

4

5 回答 5

2

Core Data SQL 存储每个查询仅支持一对多操作;因此,在发送到 SQL 存储的任何谓词中,可能只有一个来自ALLANY和的运算符(以及该运算符的一个实例) IN

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html

可能发生的是:

  • 如果早期条件之一评估为TRUE,则不评估其余条件,因此不会发生崩溃
  • 如果你得到OR (ANY contactItems.FirstName contains[cd] '%@')TRUE,你第一次使用ANY,不会发生崩溃
  • 如果你得到OR (ANY contactItems.LastName contains[cd] '%@'),你得到你的第二次使用ANY崩溃发生

您需要单独执行 ANY 并组合结果,可能使用NSCompoundPredicate

于 2014-01-09T16:26:40.217 回答
2

是的,您不能将评估为集合的表达式作为 fetchRequest 谓词的一部分。 这是在文档中

Core Data 不支持聚合表达式。

于 2011-05-26T21:30:21.763 回答
1

在检查 NSDecimalNumber 经度的谓词中发现了一个类似的问题,其中一部分出现longitude<-23并导致obj_c_exception_throw没有更多详细信息。解决方法是确保在 之后有一个空格<,即longitude < -23. 它基本上因为一起而崩溃<-,但不是>-

NSPredicate 抛出一些奇怪的未记录错误。

于 2012-11-23T20:33:21.467 回答
1

LeadID是否是一个 int 属性?我刚刚遇到了同样的问题,构建了一个谓词,我在其中检查一个或多个属性是否包含搜索词。它在大多数情况下都有效,但时不时地它会像你的错误一样失败。

问题是我检查的所有属性都是字符串,除了一个。当我从谓词中删除该属性时,一切正常。

我怀疑10076173是数据库中某个对象的 LeadID 的 int 值。看起来 Core Data通常会像您期望的那样将 int 转换为字符串,但有时它不会,那就是发生错误的时候。CONTAINS运算符对整数没有意义,它会崩溃。


作为进一步的证据,我尝试将谓词更改为使用LIKE而不是CONTAINS,但我得到了一个相关的错误,最终让我知道正在发生的事情。谓词是

itemNumber LIKE "*test*" OR model LIKE "*test*" OR productDescription LIKE "*test*" [..snip..]

例外是

“无法对对象 1008 进行正则表达式匹配。”

那时我意识到 1008 看起来很熟悉......就像一个 itemNumber,它是一个 Int32。


至于为什么 Core Data 通常(但并非总是)在您使用 CONTAINS 运算符时将 int 属性转换为字符串,我不知道。但我确实知道谓词工作正常,直到上下文未保存更改:特别是当对象的多对多关系属性发生更改时。

于 2012-03-02T22:20:40.287 回答
0

我似乎记得在 Core Data 中的集合也有类似的问题,我的 fetch 谓词不知何故导致 SQL 无效(其他数据存储类型工作正常)。这不是一个理想的解决方案,但如果您有足够少的对象,您可以进行完整的提取,然后在事后过滤结果集。

于 2011-05-26T20:25:14.007 回答