我试图创建一个NSPredicate,它可以处理两个属性的总和,并将它与对象的另一个属性进行比较:
Object.property1 + Object.property2< Object.property3
我尝试过(%K +%K)< %K但没有成功。
PS:甚至可以使一些属性为空。
我试图避免制作大量的复合谓词。
谢谢, 林
答案 0 :(得分:2)
假设您使用的是SQLite持久性存储,则fetch谓词将转换为等效的SQLite WHERE子句。因此,NULL值的处理由SQLite确定。来自SQLite documentation:
将任何内容添加到null都会为null
因此,如果谓词中的任何属性为NULL,则总和将为NULL。 Predicate Programming Guide也明确表示必须单独测试NULL值:
比较谓词与null匹配除null(nil)或NSNull null值之外的任何值....如果要匹配空值,除了其他比较之外,还必须包含特定的测试... < / p>
因此,您必须在谓词中显式测试空值,正如@ Kamil.S在他的回答中所做的那样。有一种方法可以使它更容易阅读和处理:用条件表达式(相当于property1 == nil ? 0 : property1
)替换属性值。您可以使用NSExpression
(see documentation):
NSExpression *prop1 = [NSExpression expressionForConditional:[NSPredicate predicateWithFormat:@"property1 == nil"]
trueExpression: [NSExpression expressionForConstantValue: @0]
falseExpression: [NSExpression expressionForKeyPath:@"property1"]];
(同样适用于property2
等)。然后,您可以使用NSExpression
格式说明符将这些%@
值替换为谓词:
fetch.predicate = [NSPredicate predicateWithFormat:@"%@ + %@ < %@", prop1, prop2, prop3];
CoreData将条件表达式解析为SQLite CASE (...) when 1 then (...) else (...) END
子句,该子句在数据库中作为fetch的一部分进行评估:但我不知道将如何与冗长的复合谓词进行比较。 (我也只使用单个条件表达式进行了测试;我假设CoreData可以在一个谓词中处理两个或更多,但留待它确认。)
答案 1 :(得分:0)
NSPredicate *p = [NSPredicate predicateWithFormat:
@"(%K==nil AND %K==nil AND %K!=nil AND 0 < %K) OR"
"(%K==nil AND %K==nil AND %K!=nil AND %K < 0) OR"
"(%K==nil AND %K==nil AND %K!=nil AND %K < 0) OR"
"(%K==nil AND %K!=nil AND %K!=nil AND %K < %K) OR"
"(%K==nil AND %K!=nil AND %K!=nil AND %K < %K) OR"
"(%K==nil AND %K!=nil AND %K!=nil AND (%K + %K) < 0) OR"
"(%K!=nil AND %K!=nil AND %K!=nil AND (%K + %K < %K))",
@"property1",@"property2",@"property3",@"property3",
@"property3",@"property1",@"property2",@"property2",
@"property3",@"property2",@"property1",@"property1",
@"property1",@"property2",@"property3",@"property2",@"property3",
@"property2",@"property1",@"property3",@"property1",@"property3",
@"property3",@"property1",@"property2",@"property1",@"property2",
@"property1",@"property2",@"property3",@"property1",@"property2",@"property3"
];