核心数据:返回另一个实体的对象的谓词

时间:2011-07-06 09:15:44

标签: iphone core-data nsfetchedresultscontroller nspredicate

我的数据模型中有两个实体:DetailsLookup。我需要查找与具有特定属性值的特定Details对象相关的所有Lookup个对象,然后通过提取的结果控制器返回这些Details个对象。

我的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;

我需要根据Lookup属性找到search_phrase对象,然后获取所有相关的Details对象,并在获取的结果控制器中返回这些对象。

我想我必须首先搜索Lookup对象,然后遍历NSSet of Detail对象,但我不知道如何在NSFetchedResultsController中返回它们。

我试过了:

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"];

我有一个请求找到正确的Lookup对象,但我不知道如何从获取的结果控制器中获取相关的Detail对象。

2 个答案:

答案 0 :(得分:2)

首先,您在DetailsLookup之间没有定义互惠关系,只是单向LookupDetails。您需要为从DetailLookup运行的数据模型实体添加关系,并将其设置为Lookup.searchResults的对象,并且您的Detail类需要属性像:

@property (nonAtomic,retain) Lookup *lookup;

通过互惠关系,您可以通过从Detail对象开始查找Lookup个对象,并让您找到以Lookup对象开头的Detail对象。

如果您希望tableview显示Detail个对象的列表,则需要配置获取结果控制器的获取请求以获取Detail实体。根据经验,您始终将获取请求实体设置为您希望在tableview中显示其对象的实体。

谓词同样将针对Detail实体运行,因此您需要一个谓词,该谓词针对以Detail实体的属性开头的键路径进行求值。在这种情况下,我们希望所有Details个对象的相关Lookup对象具有等于提供值的search_phase属性。所以:

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

现在设置你的获取请求:

  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

将此fetch提供给NSFetchedResultsController,它将返回您要查找的Detail个对象。

总结:

  • 始终在数据模型中使用互惠关系,以便您具有灵活性。
  • 使用获取的结果控制器时,请将获取请求的实体设置为您希望在tableview中显示其对象的实体。

答案 1 :(得分:1)

如果没有一些示例代码甚至是实际的关系,很难回答,但这里有:

  • 在表A上执行初始过滤。这为您提供了一组包含许多对象的结果。
  • 使用您的过滤器和AND #Put name of the relationship here# IN (the results of 1)
  • 查询表B.

要添加的其他内容,您应该停止将核心数据视为关系数据库。这是一个对象图。核心数据可能会也可能不会使用不同的表来存储数据。你应该关注的是对象及其关系。

如果我理解正确,你真的不想要1对多,但要多对多。 然后,您可以通过查询B对象一次执行两个查询:

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