views:

71

answers:

2

Say I have core data objects of type "obj" that has a property "propertyA" and a one-to-many relationship with an object of type "sub" that has two properties, "propertyB" and "propertyC".

I want to fetch all the objs that have propertyA equal to a value and a sub obj with propertyB and propertyC set.

If it was just propertyA and propertyB, I would do

[NSPredicate predicateWithFormat:@"ANY sub.propertyB = %@ AND propertyA == %@", ...];

The problem is that I can't figure out how to add in the second property. I want only the objs that have at least one sub that has the two properties true. I've tried the following, but it doesn't work:

[NSPredicate predicateWithFormat:@"ANY (sub.propertyB = %@ AND sub.propertyC) AND propertyA == %@", ...];

I've tried it without the ANY but that doesn't work either. How can I do this?

+1  A: 

Since you have a to-many relationship with the sub object, the subs property of obj returns a set instead of a single object. To query the set, you need to use a SUBQUERY.

Subqueries have the form:

SUBQUERY(collection, $individualCollectionItem, expression-with-collection-item)

in this case you would want something like

SUBQUERY(subs,$s,$s.propertyB==%@) AND SUBQUERY(subs,$s,$s.propertyC!=NULL)
TechZen
Thanks, but I can't find anything about SUBQUERYs in any of the apple documentation. Is my app going to be rejected from the apple store if I use it?
Mike
I can't get SUBQUERY to work at all. My original predicated was:
Mike
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isdeleted == NO AND ANY appuserMessages.recAppUserID == %@", appuserid];
Mike
appuserMessages is the to-many relationship. I wanted to isTrash, so I tried:
Mike
[NSPredicate predicateWithFormat:@"isdeleted == NO AND ANY SUBQUERY(appuserMessages, $am, $am.recAppUserID == %@ AND $am.isTrash == NO)", appuserid]; but I get "Unable to parse format string". I haven't gotten any predicate with SUBQUERY to parse at all/
Mike
I might have it. This seems to work: [NSPredicate predicateWithFormat:@"isdeleted == NO AND (SUBQUERY(appuserMessages, $am, $am.recAppUserID == %@ AND $am.isTrash == NO).@count != 0)", appuserid];
Mike
Subqueries are documented but just barely. They are perfectly legal. You can't use ANY with them because they return a set.
TechZen
+1  A: 

The solution seems to be:

[NSPredicate predicateWithFormat:@"propertyA == %@ AND (SUBQUERY(sub, $s, $s.propertyB == %@ AND $s.propertyC == %@).@count != 0)",  propertyAvalue, propertyBvalue, propertyCvalue];

where the values at the end are the values you want the various properties to be equal to.

Mike