I'm transitioning an existing data model that was previously stored in XML to Core Data, so I'm trying to learn the ropes as properly as possible. Core Data is obviously one of those technologies that isn't going anywhere anytime so开发者_高级运维on, so I might as well "learn it right."
Take for example a Core Data model with two Entities:
- Person
- Food
Person has 2 one-to-many relationships with Food:
- favoriteFoods (1-to-many)
- hatedFoods (1-to-many)
(Both Person and Food are subclasses of NSManagedObject as well.)
In the previous data model, Person maintained two NSArray
instance variables. If I wanted favorite foods, I could call:
Person *fred = [[Person alloc] init];
NSArray *fredsFavorites = fred.favoriteFoods;
Easy squeezy.
I'm reading through the documentation for Core Data, and I can't seem to find the right way to obtain this NSArray given an NSFetchRequest
, because I can't define which relationship I want to obtain objects from.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Food" inManagedObjectContext:[fred managedObjectContext]]];
[request setIncludesSubentities:NO];
NSArray *fredsFavoriteAndHatedFoods = [[fred managedObjectContext] executeFetchRequest:request error:nil];
This returns all of the Food items stored in both favoriteFoods
and hatedFoods
. How can I split these up? Surely there's a simple explanation, but I don't currently grasp the concept well enough to explain it in Core Data jargon, thus my Google searches are fruitless.
The most straightforward way to get it is to simply access the relationship NSSet
directly:
NSArray *fredsFavorites = [fred.favoriteFoods allObjects];
(I've shown how to get an NSArray
from the resulting NSSet
).
Alternatively, if you haven inverse relationship set up (which you should) you could use a fetch request like this:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Food" inManagedObjectContext:[fred managedObjectContext]]];
[request setPredicate:[NSPredicate predicateWithFormat:@"ANY personsWithThisAsFavorite == %@", fred]];
NSArray *fredsFavoriteFoods = [[fred managedObjectContext] executeFetchRequest:request error:nil];
This assumes that personsWithThisAsFavorite
is the inverse relationship to favoriteFoods
. Unless I'm reading your example wrong, favoriteFoods
should really be a many-to-many relationship, since a person can have multiple favorite foods, and a food can have multiple people with that food as a favorite.
(Note that I haven't tested this, so the NSPredicate
might not be 100% correct)
精彩评论