views:

245

answers:

1

I'm trying to model a Person/Team relationship. It's a many to many relationship since a person can belong to multiple teams and a team can have multiple people. As suggested by the doc I created an intermediate entity called TeamMember. I am now trying to run a query to see if I have a list of people, whether a pre-existing Team already exists for them so I'm not storing duplicate Teams in the database

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity =
[NSEntityDescription entityForName:@"Team"
            inManagedObjectContext:[pm managedObjectContext]];
[request setEntity:entity];

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ALL %K IN %@", @"teamMembers.person",  players];

players is an NSSet of people that I'm trying to search

I'm getting the following exception:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate ALL teamMembers.person IN { (entity: Person; id: 0x1334470 ; data: {

Ideally I would like them to match exactly and not just do an IN as well.

Any help would be greatly appreciated

A: 

First, seeing your data model would be helpful but I am guessing you are doing something like:

Person <-->> TeamMember <<--> Team

I realize you saw this in the docs (which tend to make simple things complicated for unknown reasons), I have to ask; why are you doing this? Unless there is data specific to that TeamMember object then you can just do:

Person <<-->> Team

Second, your predicate is incorrect and likely unnecessary. Since you already have a reference to the person, you can query the teams that the person belongs on directly via:

NSSet *teams = [person valueForKeyPath:@"[email protected]"];

Which will give you back a set of Team objects. If you, however, remove the TeamMember object then you can simplify this query with:

NSSet *teams = [person valueForKey@"teams"];

Because Core Data uses NSSet as opposed to NSArray you don't even need to worry about duplication at this level because if you try to add the same team to the set more than once it will be ignored.

And to round out the answer, the issue with your predicate is that you cannot mix IN and ALL together in a predicate against Core Data. This is a known limitation. Therefore I recommend going the approach I described above.

Marcus S. Zarra
Thanks for the response. Yes, your guess of my data model is correct. I do need that intermediate object because there are some extra attributes that I have to store in the TeamMember object.I'm trying to figure out if there is an efficient way for me to do the following using NSPredicate:given a list of people, find a set of teams that contain only those peopleAs for you last comment. It's probably just my rudimentary understand of NSPredicates but I'm not mixing ANY and ALL am I? Or does using IN with an set somehow get translated into an ANY?Thanks again for your help on this.
I meant ALL and IN. Corrected that typo.
Marcus S. Zarra