开发者

Core Data: Predicate that Returns Objects of Another Entity

I开发者_运维百科 have two entities in my data model: Details and Lookup. I need find all Details objects related to a specific Lookup object that has specific attribute value and then return those Details objects via a fetched results controller.

My NSManagedObjectSubclasses:

@interface Details : NSManagedObject {
@privateI 
}
@property (nonatomic, retain) NSString * owner;
@property (nonatomic, retain) NSString * introduction;
@property (nonatomic, retain) NSString * id;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * created;
@property (nonatomic, retain) NSString * modified;
@property (nonatomic, retain) NSNumber * type;
@property (nonatomic, retain) NSString * desc;


@interface Lookup : NSManagedObject {
@private
}
@property (nonatomic, retain) NSDate * search_date;
@property (nonatomic, retain) NSString * search_phrase;
@property (nonatomic, retain) NSSet* searchResults;

I need to find a Lookup object based on its search_phrase attribute and then get all the related Details objects and return those in a fetched results controller.

I think I have to search for the Lookup object first, then walk the NSSet of Detail objects but I do not know how to return those in the NSFetchedResultsController.

I've tried:

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"search_phrase = %@", self.searchPhrase];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

fetchRequest.predicate = predicate;

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Lookup" inManagedObjectContext:self.context];

[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"search_phrase" ascending:NO];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:nil cacheName:@"Searches"];

I have a request that finds the right Lookup object but I don't know how to get the related Detail objects from the fetched results controller.


Firstly, you don't have a reciprocal relationship defined between Details and Lookup but just a one-way Lookup to Details. You need to add a relationship to both the data model entity running from Detail to Lookup and have it set has the recipocal of Lookup.searchResults and your Detail class needs a property something like:

@property (nonAtomic,retain) Lookup *lookup;

Having a reciprocal relationship lets you find Detail objects by starting with a Lookup object and lets you find a Lookup object starting with a Detail object.

If you want you tableview to display a list of Detail objects, then you need to configure the fetched results controller's fetch request to fetch against the Detail entity. As a rule of thumb, you always set the fetch request entity to the entity whose objects you wish to display in the tableview.

The predicate likewise will be run against the Detail entity so you need a predicate that evaluates against a keypath that starts with a property of the Detail entity. In this case, we want all Details objects whose related Lookup object has a search_phase attribute equalling a provide value. So:

NSPredicate *p=[NSPredicate predicateWithFormat:@"lookup.search_phrase==%@", self.searchPhrase];

Now setup your fetch request thusly:

  NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
  NSEntityDescription *detailsEntity=[NSEntityDescription entityForName:@"Details" inManagedObjectContext:self.context];
  [fetch setEntity:detailsEntity];
  [fetch setPredicate:p];
  //.. set up a sort however you want the details to appear in the tableview

Give this fetch to your NSFetchedResultsController and it will return the Detail objects you are looking for.

In summary:

  • Always use reciprocal relationships in a data model so you can have flexibility.
  • When using a fetched results controller, set the entity of the fetch request to the entity whose objects you wish to appear in the tableview.


Hard to answer without some of your sample code or even the actual relationships, but here goes:

  • Perform your initial filter on table A. This gives you a set of results containing a number of objects.
  • Query table B with your filter and AND #Put name of the relationship here# IN (the results of 1)

Something else to add though, you should stop thinking about core data as a relational database. It's an object graph. Core data may or may not use different tables to store the data. What you should be concerned with are the objects and their relationships.

If I understand correctly you don't really want a 1 to many, but a many to many. You will then be able to perform both queries at once with a query for B objects:

A.your.a.query == 'What you're querying for' AND your.b.query == here
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜