使用多个条件配置NSPredicate

29
我不确定如何将多个条件级联到一个NSPredicate中。
我对Core Data比较新,不确定这是否是实现我想要做的事情的正确方法。
以下是我的尝试:
有一个Photo对象,它与一个Location对象具有whereTook关系,该Location对象具有photosTookThere的反向关系。
然后,Photo对象具有一个名为isFavourite的NSNumber属性。
我想配置一个NSFetchRequest,首先检查是否存在photosTookThere,如果存在,则检查每个结果为Photo对象,并仅返回已设置为收藏夹的照片。
到目前为止,以下是代码:
request.entity = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:context];
request.sortDescriptors = [NSArray arrayWithObject[NSSortDescriptorsortDescriptorWithKey:@"locationId" ascending:YES]];
request.predicate = [NSPredicate predicateWithFormat:@"photosTookThere.@count != 0"];

如何将第二个条件级联到谓词中并返回正确的结果?

3个回答

63

只需将每个条件放在括号内,并用AND连接它们。

[NSPredicate predicateWithFormat:@"(photosTookThere.@count != 0) AND (isFavourite == %@)", [NSNumber numberWithBool:YES]];

我还建议将"whereTook"关系的名称更改为"location",将"photosTookThere"更改为简单的"photos",这符合惯例。


谢谢,我会记住以后遵守规范的。但是我仍然有一个关于 AND 的问题:2011-05-15 17:52:24.346 CL Places[14321:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath isFavourite not found in entity <NSSQLEntity Location id=1>'我猜这是因为 isFavourite 在 Photo 对象上而不在 Location 上。photosTookThere 是 NSSet 类型。我该如何告诉谓词这是 NSSet 类型,且应该检查集合中每个成员的 isFavourite 值呢? - Will
我了解了。是的,问题在于一个参数是用于位置,另一个参数是用于照片。我认为你对关系命名的方式让我混淆了。如果我理解正确的话,那么你将要获取照片,所以你的 NSEntityDescription 应该反映这一点。你需要手头上有你正在查询的位置对象。你需要将谓词更改为 @"(whereTook == %@) AND (isFavourite == %@)",[self location] 被替换为你拥有的位置对象。希望这可以帮到你。 - Mark Leonard
谢谢,我还有一点困扰,但我会进行一些额外的背景阅读,以防我错过了什么非常明显的东西。我甚至可能会重命名关系,使它们符合正确的约定。 - Will

8

我最终使用子查询解决了这个问题:

request.predicate = [NSPredicate predicateWithFormat:
                         @"(photosTookThere.@count !=0) AND SUBQUERY(photosTookThere, $Photo, $Photo.isFavourite==1).@count >0"
                         ];

6
您可以在谓词中非常简单地使用AND和OR,就像在SQL语句中指定“where”条件时一样。为了检查NULL,比如当与“whereTook”进行比较时,您可以将其与nil进行比较(whereTook = nil)。

你的意思是(whereTook == nil),否则它就是一次赋值。 - katzenhut
2
@katzenhut 单个 = 对于谓词/SQLite 是有效的条件语句。 - Andrew Theis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接